2009年2月20日金曜日

多面体描画道楽

正多面体の図を何度も書いているうちに, 結構上達してきた. 今回は正十二面体を例に, 私流の描き方を説明したい.


ここに示すのが正十二面体である. 赤がx軸, 緑がy軸, 青がz軸である. 基本の面として正五角形の頂点に0,1,...,4と番号のある面(A)をとる.

以前のブログ(2008年9月19日)にあった正五角形は, 2と3でこの基本面に接している右上の面(E)である.

とりあえず正五角形の対角線の長さを思い出してみる.

1辺ABの長さを1とする. 対角線ACを計算したい. ニ等辺三角形だから∠BAC=∠ACB=∠CBD=αである. ∠BDAは三角形の外角だから2αである. これは内側の小さい正五角形の外角でもあるから, 72度であり, 従ってαは36度である. ∠ABCは正五角形の内角だから108度で, ∠CBD=36度だから, ∠DBAは72度 =∠BDA ∴△ABDは2等辺三角形であった. 従ってAD=1. △ABCは△CDBと相似だから CDの長さをaとすると, (a+1)/1=1/a 従ってa=(√5-1)/2, 対角線の長さはa+1=(√5+1)/2≒1.6180つまり黄金比である.

これがわかれば正十二面体のAの面の各頂点のx,y,z座標が決る.
頂点0と頂点4の間の辺の長さを2とすると,
頂点0の座標:(?,-1,0) (x座標は後で決める)
頂点4の座標:(?,1,0)
頂点2の座標:(1,0,?)となる.
次に頂点3のx座標はE面の対角線なので, (√5+1)/2. y座標はA面の対角線なので, (√5+1)/2. z座標はI面の対角線なので, (√5+1)/2.
つまり
頂点1の座標:((√5+1)/2,-(√5+1)/2,(√5+1)/2)
頂点3の座標:((√5+1)/2,(√5+1)/2,(√5+1)/2)
となる.
ところで正多面体は球に内接するから, 中心から頂点3までの長さと頂点4までの長さは等しい. 従って頂点4のx座標をxとすると
x2+12+02=3*(√5+1)/2)2
従ってx2=(6√5+18)/4-1=(6√5+14)/4. x=(√5+3)/2.

座標に使う長さを l0=(√5+3)/2, l1=(√5+1)/2, l2=1とすると,
A面の頂点の座標は, 頂点を面の外側から見て時計回りに
(list (list l0 (- l2) 0) (list l1 (- l1) l1) (list l2 0 l0) (list l1 l1 l1) (list l0 l2 0))
である. 回り方を決めるのは, 隠面消去のために各面の法線を計算するから .

残りの11の面は, 対称性を考えればx, y, z軸まわりの直角の回転, yz, zx, xy面に対する反転で得られる. すなわち
B面はA面のxy面に対する反転 C面はA面のyz面に対する反転
D面はC面のxy面に対する反転 E面はA面をx軸まわりの回転のy軸まわりの回転
F面はE面のzx面に対する反転 G面はE面のxy面に対する反転
H面はG面のzx面に対する反転 I面はE面のy軸まわりの回転のz軸まわりの回転
J面はI面のyz面に対する反転 K面はI面のzx面に対する反転
L面はK面のyz面に対する反転
である. 反転の場合は頂点の時計回り順を維持すべく, リストを逆順にする.

これですべての面の頂点の座標が揃った.
上の図は正面から見た図を, z軸まわりに15度回転し, さらにy軸まわりに-15度回転してから, 正面(x軸方向)から見た図である. 前のブログの記述の「左に寄せる角度をθ, 手前に引く角度をφとする」との対比では, θはz軸まわりの回転角, -φがy軸まわりの回転角である.

すべての座標を上述のように回転し, x軸方向から見た絵を描くには, y座標を2次元画面のx座標に, z座標を2次元画面のy座標にするだけでよい.

隠面消去も簡単である. すべての面の法線方向を求める.
それには頂点リストの0番-1番, 2番-1番で, 1番から出た0番方向と, 2番方向のベクトルが得られ, この外積をとると各面の法線方向が得られる. そのx成分が正ならこちら向きの面だし, 負ならあちら向きの面である.
すべての面をこうしてx成分の負のものと, 正のものに分け, あちら向きの面を灰色の線で描画した後, こちら向きの面を黒で描画した.

いい忘れたが, 今回の計算はすべてSchemeで行い, 最後にPostscriptのファイルを出力した. 座標軸や面の文字は, こうして出来たPostscriptのファイルに追加したものである.

1 件のコメント:

shinh さんのコメント...

Shibuya.lisp で 12 面の生成部分を抽象化することはできないのか、と質問させていただいたものです。この並べ方が綺麗なものであることを理解するために、自分でもここを参考にさせていただいて実装してみました。それで気付いたのですが、「K面はI面のxy面に対する反転」→「K面はI面のzx面に対する反転」ではないでしょうか。