曲面除了可以用参数方程的形式表示之外,还可以用隐函数的形式表达,即表示为 F(x, y, z) = 0 的解。这种曲面又称之为等值曲面,因为曲面上的每个点都满足 F(x, y, z) = 0 这一条件。Mathematica 提供了绘制等值曲面的函数 ContourPlot3D。不过在这篇文章里,我们并不用它来绘制各种婀娜多姿的曲面,而是尝试用它探索、绘制一些"多面体"。
$ ?* {7 h4 h- T从最简单的开始+ o' f9 T+ V# G& y& F6 f1 ]& \
让我们从最简单的,大家耳熟能详的球面方程开始:
' [; a' Q- d- }' {8 R4 l. E
" {, U, q1 T, k6 m
方程 x^2+y^2+z^2==1 的意义非常简单:每个点到原点的距离都是 1,这就形成了一个球面。相比较之下,球面的参数方程就不是这么简单了:, ]: j/ y; z& o. X
多面体, @8 l! X) x2 v' V
从球面方程出发,我们可以看一下更一般的形式,比如 x^n+y^n+z^n==1 的图形是什么样子的: $ i7 n. i$ a7 N6 \2 B9 p1 C' a+ A
8 c- ?( U6 d! t& G1 R% {可以看到随着 n 的值不断增大,方程表示的曲面越来越接近一个立方体。这是为什么呢?我并不能完全解释,只能提出这么一个猜测。考虑如下表达式:( [# v$ S& u. @5 X* R) a4 T: ~$ ?
7 l$ m2 t1 ?% @8 m( E2 b, e9 m
这是 Lp 范数的定义,当 p 趋向于正无穷时,上述表达式的极限是:6 e( w8 w' E8 ~ S+ O
. k6 c/ h, N" u) i ?+ q0 i" N- n# \" ^也就是 n 个绝对值中的最大值。把这个结论放到我们的方程 x^n+y^n+z^n==1 上,当 n 不断变大时,在不同方向上就不断接近 | x | == 1、| y | == 1、| z | == 1 三个方程,而这三个方程恰恰是立方体的六个面:x = ±1、y= ±1、z= ±1。根据这个猜测,我们只要能知道多面体各个面的平面方程,就能类比的求得类似上述立方体的“多面体渐近方程”。更进一步的,多面体各个面的平面方程,只要知道面法向量就可以确定平面方程了,如果面法向量是 (a, b, c),则成对的平面方程就是 a x+b y+ c z = ±1。 利用 PolyhedronData 可定义求各种多面体法向量的函数如下:
: V* Q; D) t$ D# K
0 q( W% r) r% t, v; m2 Z# A接下来就让我们用实际计算来验证一下这个猜测吧:4 J8 Y* z c9 Q6 Z4 ~; N2 K
正八面体
' t x2 a1 Y+ ]6 T求正八面体的法向量:
; l4 h! g, ?) P% m5 V, \化简并去除方向刚好相反的法向量,因为之前方程的常数项 ±1 可以由一个法向量得到两个相对的面的方程:
, a" `9 u9 o# H4 K: z" J
1 ~3 v; ^' T8 L
然后就可以根据这个求八面体渐近方程了:0 _# J$ ?6 y4 ^. S* g: h
! h! U- H& m' J5 _, h* X+ _- T- \% d
8 X3 \& k+ A% `5 I0 D
正十二面体 4 e5 i% v* B3 X
正十二面体的法向量:
- k8 f R# f, q) | T9 ~
4 {$ T- ?) h/ R1 k' B化简并去除方向刚好相反的:4 C6 Q/ `7 S- s7 i0 S$ ` K8 |
. o9 S0 Y: l- ^4 e( G隐函数表达式:
6 |" @% E! Z- c5 J
& O' R$ \! _5 r! Y/ y' ~
4 C- \ W* ]$ y0 N% R, l' {4 K为了计算方便,我们用数值近似取代根号形式:
绘制图形,可以看到,随着次数 n 的不断升高,图形越来越接近正十二面体:# T0 @1 G2 |5 O' _. c0 R
. J! } z; u& a3 b, Y# S十二面体
% t4 _6 u- M/ b# C' d3 N: M' b2 Z计算各个面的法向量:+ m# z% _4 y: l5 W; M9 B
9 g& k6 l2 b: ~1 h" j
化简并去除方向相反的:
0 m9 q1 \$ t R6 D2 S2 t
; Z: |. e- a/ c" _得到方程左侧表达式:
! W5 N* M8 D( C3 z0 R3 F( B为了计算方便,取近似值:
7 P5 V% F+ _" S! R% f) J6 \( A$ M
2 m9 ]4 e Q& P7 A7 f绘制正二十面体的曲面方程:
- e: ~* n- S1 W3 Q5 r
绘制正二十面体的曲面方程:
; W- J) o6 n$ u7 j K8 t
复合多面体 从上面的计算可以看到,根据猜测做的推论基本上是对的:确实据此得到了各种正多面体的渐近方程并成功绘制了出来。但同时也可以看到,这种方法有很多局限性。首先,所生成的多面体必须有平行的相对的面,这样采用的法向量才能一个顶俩,发挥应有的作用得到对应的多面体。五种正多面体里,只有四种满足这个条件,还剩下一个正四面体不能用这种方法表示。其次,用这种方法只能表示凸多面体,所谓凸多面体,就是内部任意两点的连线仍然落在内部的多面体。这两个问题都是可以解决的,解决方法是引入指数函数。
/ Z$ \7 |+ k) J+ \$ t正四面体 C7 ~( q8 u/ w5 a( |6 X* G
计算正四面体的法向量:2 P# G! ?! r* {8 A, u
化简:
如果用之前的高次方程的方法,那么只能得到一个朝向比较特别的正八面体,因为每个法向量都生成了两个平面:
' k% P% A% [' f: Z
% X, |) ^8 q- G( d% V& X而改用指数,则可得到如下表达式:
9 e: F* y- s6 V- U: ^: K. S0 m
7 W3 l( c. y: e' {9 w; }6 b$ B A3 m
以此作为隐函数果然可以画出正四面体:+ `# g$ z) c- F9 \% i" t9 b! K
& J: u# K0 L* Y5 |: H; S为什么这样可行?我也只能给个近似的猜测:对 E^(a x + by + c z)==C 这样的方程,两边取对数就是 a x+ b y+ c z==log C 这就是一个平面的方程,把几个这样的平面方程加起来,就"围成"了一个多面体。而指数的增长保证了每个方向上不会受其它项的影响,保持大体是个平面。 " M" o- D" o* X* I i- ^2 Y
另外还值得指出的是,可以在指数上再加次数,让这样生成的多面体的边缘更加"锐利": 0 ]: s) \2 P$ I ^1 `4 e( F
: ^# p+ ^. F; X4 h1 D2 C$ ?9 Z
星形八面体 在各种各样的多面体中,有一类多面体可以看作是若干基本的多面体彼此叠合组成,我们称之为复合多面体。比如下图所示的星形八面体,就可以看作两个正四面体彼此叠合而成。
1 f6 X+ e) q: O: K0 l! N
' m/ ~4 x- R4 m4 c4 \
观察这个复合多面体的面的组成指标可以发现,前四组只包含顶点 2、4、5、8,后四组只包含顶点 1、3、6、7。这恰好是各自组成两个正四面体。我们可以照样算出这八个面的法向量,然后分组各自生成两个正四面体曲面:
9 M# a6 _3 E5 i0 W$ h5 K" O2 N
. f0 T) f+ f5 j6 }$ `/ r$ e求法向量,化简并分组:% c5 |( b- E: ]; t- H
: Z, Z, o1 i# f7 {! Q/ j
得到两个指数和的表达式:
: a0 f$ K+ p3 X% U6 a
6 L, S# s, B% {4 X
分别绘制可以看到两个正四面体:" O& z0 E0 U5 c* S4 O
6 j3 ^2 [) [& y如何从这两个四面体得到想要的星形八面体呢?直接相加肯定是不行的,那样得到的就是正八面体了。这里我们采用 The Nature of Mathematics and the Mathematics of Nature 一书中提到的一个小技巧:把两个方程表达式再次放到指数上。这个技巧称为 Exponential Scale:
! S+ Y: K7 q2 L. H7 T
7 F& V8 U& n9 h可以看到,这个方程确实可以绘制出星形八面体:
$ b) \6 j/ E8 A) T" ^
. S5 ~" q" g# |3 ?可以把旋转观察这个星形八面体曲面的过程输出为动画:
7 u% J* S; P( l' k; R% h
3 ~* O5 |' N! K! V, C9 D3 m
. `& \; Y' m7 |* M
, \/ V9 q. ~( u. |9 D8 N% X五复合正四面体 3 d7 {9 R' ?) N+ j/ {
我们可以再举一个例子,五复合正四面体,这是由五个正四面体内接于一个正十二面体形成的复合多面体:
4 h8 v2 B8 _1 u" W* }7 w$ z' I) _2 c照例求面法向量,化简并分组:
M X7 K# x7 q1 j1 V3 ^- F4 ]' b
5 K o' i* |* i* B J得到方程:: H& m8 a# x8 B! N, S% k2 ]' ?
* i+ U3 m4 Y& d) t. G2 [! n) O8 c
绘制可以得到五复合正四面体的近似曲面(警告:由于项数太多,运行绘制速度很慢,运行时请耐心等待):
) W* {! h( e9 S1 k
8 J g4 \6 v9 \' {# {我们也用它生成一个旋转观察的动图:
5 i. r3 c f5 E1 Y2 F# |" a4 l1 i5 D$ F8 g4 c! {; {0 j
; s( t/ K' w) `+ R& `: ^" @
更多的复合多面体
6 w' D3 a! r) ^7 C/ P/ b0 P只要是由凸多面体组成的复合多面体,理论上都可以用上面的方法,先求得各个多面体的方程,然后“抬升”到指数位置,得到复合多面体的方程。Mathematica 提供的PolyhedronData 函数里有许多复合多面体,我全部列在下面,感兴趣的读者可以自己实验生成想要的复合多面体曲面。8 F- s8 |5 ]1 z
. i/ a; s) b6 Z2 i1 @' b/ x
' M% n, ~! [9 b1 s) u6 P1 U
对此有兴趣的,欢迎联系我们共同探讨。
6 h0 H' p2 ~# nmarket@asdoptics.com & y( \- c# g( m4 z7 C
www.asdoptics.com
L" B8 s8 r& {( F) U' X7 H' K5 l( C8 F: c; B* v
|