曲面除了可以用参数方程的形式表示之外,还可以用隐函数的形式表达,即表示为 F(x, y, z) = 0 的解。这种曲面又称之为等值曲面,因为曲面上的每个点都满足 F(x, y, z) = 0 这一条件。Mathematica 提供了绘制等值曲面的函数 ContourPlot3D。不过在这篇文章里,我们并不用它来绘制各种婀娜多姿的曲面,而是尝试用它探索、绘制一些"多面体"。
3 n( l0 @& P2 |* }( f n4 l0 z从最简单的开始6 c; V! m5 B; u
让我们从最简单的,大家耳熟能详的球面方程开始:1 b1 z( t0 L" `, \" E9 h( P
! m% D" a6 s- G0 n+ X
方程 x^2+y^2+z^2==1 的意义非常简单:每个点到原点的距离都是 1,这就形成了一个球面。相比较之下,球面的参数方程就不是这么简单了:6 E! G: Q/ l! y
多面体
* P- F7 f* M. y7 z2 h$ k从球面方程出发,我们可以看一下更一般的形式,比如 x^n+y^n+z^n==1 的图形是什么样子的: . C( d B# ?# D6 ~ A$ u V& ~$ D
/ y! o" y0 P& F" I6 [( ?3 K
可以看到随着 n 的值不断增大,方程表示的曲面越来越接近一个立方体。这是为什么呢?我并不能完全解释,只能提出这么一个猜测。考虑如下表达式:1 X9 a8 n: p: L
u& m: J" o2 M, y+ C/ }: p
这是 Lp 范数的定义,当 p 趋向于正无穷时,上述表达式的极限是:0 @3 W9 ~5 P. y) ]* [7 j
- _, ^* W% T: O1 A9 h" C0 c* t( _也就是 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 可定义求各种多面体法向量的函数如下:
0 v+ c0 \# t' }
" Y2 m" D; X/ N- Z$ K
接下来就让我们用实际计算来验证一下这个猜测吧:
9 U8 k1 @7 }* X2 J r正八面体
3 k; }) |$ z/ i0 c& E. C求正八面体的法向量:
) Y% X6 z9 \4 \1 ~( I; ]化简并去除方向刚好相反的法向量,因为之前方程的常数项 ±1 可以由一个法向量得到两个相对的面的方程:* W# K0 h8 i; {! `
5 v0 n! { A f t
然后就可以根据这个求八面体渐近方程了:
: ~9 B% I$ r& E4 |$ p* W
& Q A* Z( Y3 `/ d2 S
9 G, g5 `8 B" L+ H ?9 g
正十二面体
9 A2 v u1 e0 u9 d正十二面体的法向量:
1 `- I# J* v& H+ s7 {- E
7 h& e- ^: s0 A8 q! f k
化简并去除方向刚好相反的:
3 q1 K; a' R4 F" k+ u- E- y
9 f! |; U7 n+ Z, F0 e3 e2 ~$ `4 {
隐函数表达式:6 F: A; z% j: k1 O/ R6 V( b) I
. q8 h3 n# I( u3 ^& V) x" c2 I9 I9 q& ]/ T. p9 F) A2 T
为了计算方便,我们用数值近似取代根号形式:
绘制图形,可以看到,随着次数 n 的不断升高,图形越来越接近正十二面体:
0 a& r2 O0 p* G- z, j! w7 s
?* O0 B6 G/ V. b9 e' d十二面体
% A2 Y e9 G8 L: c9 e# ~计算各个面的法向量:6 j+ H1 j z) [- D. g
; Z9 m3 w' [) {/ g. s; d. n
化简并去除方向相反的:
0 J" t& O: N+ [) h8 l/ |- s2 D5 m
3 z- w( d+ q0 @" a1 [5 W9 c! A
得到方程左侧表达式:
; g9 f0 }- [) n3 _( T% F6 q
为了计算方便,取近似值:
8 J* [! E6 H( Z0 D B: O
# o6 }- n( G" P- M& G, h绘制正二十面体的曲面方程:
U) ]: p/ b% ?1 S% v+ K& m5 ^2 D绘制正二十面体的曲面方程:
) C3 X+ ~7 o$ ^" m
复合多面体 从上面的计算可以看到,根据猜测做的推论基本上是对的:确实据此得到了各种正多面体的渐近方程并成功绘制了出来。但同时也可以看到,这种方法有很多局限性。首先,所生成的多面体必须有平行的相对的面,这样采用的法向量才能一个顶俩,发挥应有的作用得到对应的多面体。五种正多面体里,只有四种满足这个条件,还剩下一个正四面体不能用这种方法表示。其次,用这种方法只能表示凸多面体,所谓凸多面体,就是内部任意两点的连线仍然落在内部的多面体。这两个问题都是可以解决的,解决方法是引入指数函数。' e4 q6 Q; l+ z/ ]+ |
正四面体 0 \" W& p" t1 N" t( A y- P1 B
计算正四面体的法向量:
% L! T2 \" `3 ?# G+ _" M5 W6 u t. j
化简:
如果用之前的高次方程的方法,那么只能得到一个朝向比较特别的正八面体,因为每个法向量都生成了两个平面:
" ?8 i, q; b0 C, f
) ^5 K7 S9 z- y# d3 m& W! N9 @# ?
而改用指数,则可得到如下表达式:
& C, u {. h' T4 A# w9 N
" ?9 g. b# m1 f以此作为隐函数果然可以画出正四面体:& i! V) ~- c8 g$ D' p3 [+ H% V
* @! M' O0 H$ I5 @7 b1 K+ L
为什么这样可行?我也只能给个近似的猜测:对 E^(a x + by + c z)==C 这样的方程,两边取对数就是 a x+ b y+ c z==log C 这就是一个平面的方程,把几个这样的平面方程加起来,就"围成"了一个多面体。而指数的增长保证了每个方向上不会受其它项的影响,保持大体是个平面。
6 l, a+ G2 b4 o2 k6 u f另外还值得指出的是,可以在指数上再加次数,让这样生成的多面体的边缘更加"锐利": ; S( G2 J& E/ b( Q% r0 J
0 v# x: q* }! R+ [' P' a
星形八面体 在各种各样的多面体中,有一类多面体可以看作是若干基本的多面体彼此叠合组成,我们称之为复合多面体。比如下图所示的星形八面体,就可以看作两个正四面体彼此叠合而成。
" o" F1 D& V8 U9 A
. q/ |: ~% B, Z" {观察这个复合多面体的面的组成指标可以发现,前四组只包含顶点 2、4、5、8,后四组只包含顶点 1、3、6、7。这恰好是各自组成两个正四面体。我们可以照样算出这八个面的法向量,然后分组各自生成两个正四面体曲面:
: n* }; Q( v8 t2 F- G' V. p3 j
/ n* X8 }7 n) K' k6 y求法向量,化简并分组:
8 F1 v+ k3 y4 e" v" f
! v A4 k# `- V/ |3 r; Y) g得到两个指数和的表达式:) q2 g9 c; b& |
8 ?5 n- c5 }( K/ ~分别绘制可以看到两个正四面体:
0 ] R1 G+ y; J" {3 r" f4 |4 e
; m, r- j( _: Z' z- P
如何从这两个四面体得到想要的星形八面体呢?直接相加肯定是不行的,那样得到的就是正八面体了。这里我们采用 The Nature of Mathematics and the Mathematics of Nature 一书中提到的一个小技巧:把两个方程表达式再次放到指数上。这个技巧称为 Exponential Scale:
4 z% y, v( o( ~+ M7 }
. ^& @! [5 l; s$ o' K/ @' B* J. s( B可以看到,这个方程确实可以绘制出星形八面体:
) _# l7 v. M5 g, ]
# R3 y# n4 s; ^+ O可以把旋转观察这个星形八面体曲面的过程输出为动画:
3 H8 w3 O( ~. B j1 t6 Y
9 N* g7 X6 N! `
+ e4 M4 C& H! b9 b2 W# w% j3 d
6 I* u+ a6 |" U+ A+ F$ {% q五复合正四面体 % e R: d$ X' d% T1 B
我们可以再举一个例子,五复合正四面体,这是由五个正四面体内接于一个正十二面体形成的复合多面体:
) Z% O4 H; {$ n m) O( d
照例求面法向量,化简并分组:
/ j/ y1 I8 Q( K/ ?2 B3 i1 Z- K# z
得到方程: I# H& k9 l# F; w0 j6 Y& f0 m" C
4 x- _. V( p! o+ _! k* R# q6 o _绘制可以得到五复合正四面体的近似曲面(警告:由于项数太多,运行绘制速度很慢,运行时请耐心等待):
1 @1 g- A( y. x, c2 P4 g$ W
: O- z8 w: i5 |# N, d* u) S
我们也用它生成一个旋转观察的动图:
8 H- @! w, y1 i( H2 \& G/ d) }
& L' u5 g; i- e$ w, u6 b
. O; |% D& u( a+ o3 o1 K
更多的复合多面体 $ R$ S, o( R F( N
只要是由凸多面体组成的复合多面体,理论上都可以用上面的方法,先求得各个多面体的方程,然后“抬升”到指数位置,得到复合多面体的方程。Mathematica 提供的PolyhedronData 函数里有许多复合多面体,我全部列在下面,感兴趣的读者可以自己实验生成想要的复合多面体曲面。
& E3 a- U; l _( c Z
7 x: R2 r4 E- Z* d/ A" n; d
' y* ` |: v( u* W1 {1 P) Z* {' l+ q对此有兴趣的,欢迎联系我们共同探讨。
. F+ e" O7 Q5 D+ B: Jmarket@asdoptics.com
! M6 P4 m& l8 h) X2 [ L! dwww.asdoptics.com ' q$ u% `) N' C7 N3 J# b: d
6 E$ |/ ^" f8 f' M1 U9 i
|