2009年2月23日月曜日

多面体描画道楽

PostScriptのすごいのは, 座標の拡大縮小, 移動, 回転などをやってくれることである. 別のいい方ではaffine変換をしてくれる. 例えば下の図で, 左上は縦横等間隔に平行線を引いたものである. 右上はひしゃげた形になっているが, 等間隔の平行線に違いはない.

PostScript的な表記では, 左の図のp(x,y)は右ではp'(x',y')に移動していて,
x'=ax+cy+tx
y'=bx+dy+ty
となっていて, 今の場合, パラメータはそれぞれ
a=1.2, b=0.5, c=0.3, d=0.8, tx=ty=0
である. (tx=0だから, 2つの図は重なる筈だが, 見えにくいのでずらしてある.)

左下の正五角形を同じように変換したのが, 右下のである. こういう変換は文字フォントについても出来て, 少し前までの国土地理院の地形図は, 山の名は右肩あがりの文字, 川や湖, 海の名は上端を左にずらした文字(イタリックと逆)で表示してあった. 次の箱根山と芦ノ湖がその例だ.

さて, 改めて考えてみると, 正十二面体の各面の投影された五角形は, 真正面から見た(つまり通常の)正五角形を適当にaffine変換したものであった. だから各面の変換パラメータ, a, b, c, d, tx, tyが決れば, その環境で単に正五角形を書けばよい筈である.

x方向についてa, c, tx, y方向についてb, d, tyを決めたいから, 直線上にはない3つの点があればよい. 前回のA面について考えれば, 頂点0, 2, 4の真正面から見たx, y座標(3次元でいえばy, z座標)
0=(-l0, 0), 2=(0,l2), 4=(l0,0)
であったから, これがそれぞれ(x0,y0), (x2,y2), (x4,y4)に移動したとすると,
x0=a.(-l0)+c.0+tx, x2=a.0+c.l2+tx, x4=a.l0+c.0+tx
y0=b.(-l0)+d.0+ty, y2=b.0+d.l2+ty, yr=a.l0+d.0+ty
従って
tx=(x0+x4)/2, a=(x4-tx)/l0, c=(x2-tx)/l2,
ty=(y0+y4)/2, b=(y4-ty)/l0, d=(y2-ty)/l2
と得られる.
各面についてこれらのパラメータを計算すると, PostScript風には
gsave
[a b c d tx ty] concat
l0 neg 0 moveto l1 neg l1 lineto 0 l2 lineto l1 l1 lineto l0 0 lineto closepath
stroke
grestore
で描けてしまう. 分かってみるとなーんだということになる.

前回の最初の図の各面にあるA, B, C,...など面の名は, 実はこうして描いたものであった. (だから見えない面の名は裏返しになっていた.)

これまでは5つの頂点すべてを変換していたが, この方式では3つだけでよい. しかし, 正多面体では正三角形の面のものが多いから, これでは得にはならず, 正多面体描画道楽で利点があるのは正十二面体(と正六面体)だけであるが, こういうことを考えておけばまた役立つこともあろう.

0 件のコメント: