自我开始接触Wolfram起,我参与了一些不同的项目,对于第十二版来说,我主要的关注点在于用Wolfram语言复制均匀多面体的模型,以确保数据可以达到某个标准让模型更精确,包括精确的坐标、一致的面朝向和一个可以为每个固体创建网格模型的封闭区域。 使用多面体的可视化模型是一回事,但是用数学方法分析它们则要复杂得多。从多面体的参考模型开始分析,我发现Wolfram语言让均匀多面体的数学分析变得有效而简便。
/ o+ t$ |6 x- a ]0 w: G7 ?% u# i8 G5 k( w- _) |0 p2 L
0 d. }3 K8 ^$ T q% _7 z3 q8 R# A多面体是由平面多面体面组成的三维几何体。相邻的面相交于边,边相交于定点。多面体的奇妙已经超越数学家研究的范畴了。古希腊人证明有五个正多边形或称为柏拉图多面体(正四面体、正方体、正八面体、正十二面体)都新引进了第十二版:
6 a3 [' M. o5 v, }& |
/ a0 j5 }, B. t$ B2 u4 L十六世纪天文学家开普勒甚至用多面体研究在他那个时代已知的太阳系六个行星的轨迹比率关系。模型展示了柏拉图体镶嵌在球体内,每个多面体都接触两个行星球体。开普勒相信这能解释行星间的距离和为什么存在恰好六颗行星:
4 j7 {5 n. b# h. k9 I' a5 g
但是,直到欧拉才发现了一个关于多面体的重要公式,内容是正多面体顶点的数量减去边数加上面数等于2:8 F5 I" A$ {0 f; ^4 F) r
V – E + F = 2) T, r' \) s( O% c9 }9 `. a
这个等式的左边称为欧拉-庞加莱示性数,我们可以在第十二版中用EulerCharacteristic来测试:% k" M x: w8 P
* o( ^1 u( `0 r. i! Z: Y/ `9 P* }
在那时,多面体的理论主要集中在测量角度、求多面体面的面积和边长等属性。而欧拉则开始不同的属性对多面体进行分类。就像哥德巴赫的理念一样,欧拉也讨论了他认为的关于多面体的重要部分:面、顶点和边。这样,欧拉不仅提出了他著名的欧拉-庞加莱示性数,他还为拓扑学的发展铺平了道路:他不像传统几何学一样把重点放在距离上,而是像拓扑学一样使用其他属性来描述一个面。/ S3 q& @' e$ @1 S: ]+ T
多面体到底是什么? : ^7 l# G% d$ n H; @8 }
尽管为几何形状建立模型看上去是一件很直接的操作,但是还是有一些特殊的事情需要考虑。对于什么是多面体这件事总是有不同的观点。像前面提到的一样,最常见的概念是,多面体是由顶点、边和面组成的。但是,现在依然没有一个普遍接受的多面体定义。有些人说多面体包括凸多面体和非凸多面体,而另一些人认为多面体只是凸多面体。多边形的研究者还在其他很多方面有争论。如果多面体内有多边形相交呢?模型内部发生的事情是否应该考虑?那使用五角星形和其他多边形的均匀多面体呢——这种情况也有争论?模型是否应该用空集来描述?这样有争议的观点使得为多面体建立模型更加困难。特别的均匀多面体
, R$ H' h% u& A8 l4 B: Q多面体有很多种,但是这篇博文会着重75种特殊的多面体,一般称为均匀多面体。均匀多面体有点传递的特点,每条边只有两个面;更重要的是,所有组成这些多面体的多边形都是正多边形。在第十二版中,我们可以使用EntityList和UniformPolyhedron来为我们提供均匀多面体的信息:, y! d7 T0 [- ~2 [% W1 G
8 Y1 x1 @! ^4 Q6 t2 j从模型中提取信息 . K# b% Q" w+ y# Z2 L1 g" }" i# C
一般能找到的多面体模型长这样:
! _- ?0 {7 R) q% h n/ Z+ n
$ p Z+ f6 ?; d p
+ ^( g( M$ z" I3 ~0 ^" |4 v) P0 G这些是均匀多面体的图形表示。在第十二版之前,PolyhedronData有其中一部分多面体的信息。在第十二版中,我们现在可以把第一个模型表示为72个面和30个顶点:
* h8 L" P( f, j% A" n" b; P
: o0 W% `/ K6 t* y. T
使用FaceForm,我们可以看到在某些区域多面体面的朝向有翻转:
4 x- b/ j/ W, u1 _
4 z/ ^8 i) Z# f这个模型有相交的多边形,也没遵守多边形的“右手法则”(如图所示),说明它的面朝向不对:
( k/ L: z6 Z4 B# X v% `- o* t2 w' c" M
( o; f4 A1 Z' e3 K" U为了在这个项目中复制多面体,必须改变这些模型来解决这些问题。我的第一个方法很简单,使用标准模型得到顶点,使用这些顶点重构多面体,然后根据右手原则改变面的朝向。下一步是将模型等比例缩放到单位尺寸,并收集精确的坐标。可惜的是,在数次尝试获取精确坐标失败后,我得出结论,从这些模型中获取坐标并不是一件简单的事。现在是时候往回看看并花时间进一步了解多面体。
" u, f( p. I# ?2 B! G创建几何体
6 P& V( h# ^% l# l3 E i有一些多面体有共同结构的顶点和边。这样,我就可以整合PolyhedronData里有的均匀多面体数据重建这些有类似属性的多面体。用这种方法,我可以汇集某个均匀多面体和它的“兄弟们”,并“调整”面以创建多面体。我们尝试一下创建小菱方八面体。使用在PolyhedronData中小菱方八面体的顶点和共同边的数据(在这个例子中是12个方形面)并使用FaceForm确保所有面都遵守右手法则:
' i6 l. T* i' P4 E. y
! T* C6 V3 y& T" b$ T* n& O$ ~! }% z: |
最后以下面多面体的“壳体”结束:
+ Q. ^1 p l" K0 r, V
使用FaceForm,我们可以看到在某些区域多面体面的朝向有翻转:
% P2 k. r; J" Z1 c# j
/ M4 T1 K) |1 _* z; [ x; b& O* X0 `现在我们把新的八边形面加入壳体中:
* W/ ^4 K, K7 @6 H \! |" C X
7 z A8 ]* u( S- L: q. M6 U* k8 {4 N这样就创建了一个新的小菱方八面体!但是,这个模型有翻转面。创建多面体的时候,通常不会考虑到有些面可以从两边被看到,不然就会产生翻转面。修复这个问题的一个方法是把多边形分割并遵守右手法则。在这个范例中,八边形就变成了三角形和矩形。
1 C+ j& ?6 b v5 I- {* P
4 P4 u+ A( p" j3 H& V/ z p' v) [
5 i* I& I. V* Z' O4 L+ v, {6 ~
这个小菱方八面体就完成了!使用FaceForm,我们可以检查知道这个模型的面朝向正确。
2 D9 [. [9 M; y* N, ?. {8 Q* v
$ l" e$ g% E' t x" U
模型中不再有面朝向的问题,这样这个过程可以重复于大多数均匀多面体。
! x9 {1 ? S/ f6 p# q' H4 ?" _更复杂的模型需要不同的方法,对这些模型,我们可以使用二叉空间分割 (BSP)树。有了精确坐标和面之后,我们可以重新创建多面体,但是如果确保所有面的朝向都正确却还不清楚。对于像小菱方八面体这样的多面体,可以很容易看出哪里的面应该被分割才能让多面体保持连续性。对于其他多面体,如大二十面半十二面体(great icosihemidodecahedron),决定哪个面应该被分割这件事就不是那么容易了。所以此时需要借用BSP树来让我们观察网格图形的哪个面应该被分割。这里我们有一个使用从其凸包而来的精确坐标所得的没有变形体的大二十面半十二面体( icosihemidodecahedron),二十面体和与其有相同边结构的大三十二面体( icosidodecahedron )(三角面)和(great dodecahemidodecahedron)大十二面半十二面体(十字形面):. t* i. L( D+ `, H9 `! i
2 J( a4 W7 v" T: q7 U+ P) g. P: K$ W使用FaceForm,我们可以看到这个模型有翻转面:
; A# Q3 M: h( T, C0 t; ?
; U4 D$ N7 _ I; u1 t% a3 @这个问题可以按照小菱方八面体的类似方法解决。但是,很难能看出哪里的面需要被分割。这就是BSP树派上用场的地方了,因为它可以更近距离更清楚地看到应该在哪里分割多面体的面,并提供需要有新分割的坐标。使用BSP树,网格图被转化成了网格分区,然后可以用来了提取必要的信息。网格图被分区后,可使用Graphics3D来看当前的面朝向,并集合需要做分割的地方:
" D4 F3 ~9 Z3 i- H
4 W4 w5 A# r+ A; R+ p- e
一旦决定了哪里的面可以被分割,可以从BSP树方法中得到的网格中提取坐标。6 o7 t6 U7 x/ D0 n3 l( X
切割角? & e7 @$ g6 h. f" z, P
虽然我们有所有均匀多面体的精确坐标,有些多面体中相交的面使得很难决定在哪里分割多边形,尤其是在非凸多边形中。很难分割的多面体范例包括扭棱十二合十二面体(snub dodecadodecahedron)、大后扭棱二十合三十二面体(great retrosnubicosidodecahedron)和大双斜方三十二面体(great dirhombicosidodecahedron)等。从可视化和计算两个方面考虑,很难找到哪里的面需要被分割才能生成有精确坐标和正确面朝向的原模型副本。这个过程即使在BSP树分析后,如果在存在很难分辨大量重叠面、星形多面体的孔洞等的情况下还是会非常困难。5 m7 n ?$ i: @5 A% v8 Y
: j8 l% S% g1 ?8 x0 ^. M, w/ \. o所以这时候我决定回到基本,手动生成这些多面体。我想要避免打印出之前制作的多面体网。如果我使用了网,之前计算的时候遇到的问题不一定会出现。为了做到这一点,我切割了一些多边形以生成多面体。对于小菱方八面体,我用了一个两英寸的比例标尺生成了必要的正方形和八边形。然后我马上就遇到了之前计算时碰见的问题:相交的多面体。这个问题可以用在多面体中制造割口的方式解决。但是我立刻意识到,八边形面可能会需要多次切割。在数次多边形切割后,我终于生成了小菱方八面体的八边形架构。最后一步就是应用那些方形面,最终生成了小菱方八面体。2 P* }2 O$ K/ z7 N! r" }
! V. Z: u4 \; O' m4 Q使用这个用切割新生成的小菱方八面体,我还可以三维打印这个模型,以和纸面模型做一个对比。
7 }$ L0 l3 i& X7 \" k1 |( [3 @9 K
& b1 o* r2 R" m6 [, q7 G
根据我手动建构多面体的经验,必要的操作是要分割多边形,才能最终把多面体组合在一起。在我逐渐可以熟练操作某些多面体后,我现在可以着手试一试之前在计算上欺骗了我的一些多面体,比如大斜方截半二十面体(great rhombicosidodecahedron)。在这个过程中我还在发现新的思维方式,虽然还是有很多挑战需要解决——即使是要生成这些多面体的纸面模型也很难,而且在哪里做切割也不是很明确。我们还会继续研究,我发现Wolfram语言中的均匀多面体——所以时刻注意我们的大反扭棱三十二面体哦!
* e; V1 i. J4 S4 e9 e3 F! T6 M: T
1 ?2 }* a+ O2 ]; B6 l8 D |