ラベル moebiusの帯 の投稿を表示しています。 すべての投稿を表示
ラベル moebiusの帯 の投稿を表示しています。 すべての投稿を表示

2009年4月9日木曜日

moebiusの帯

今回もコンピュータ作図の話題である.

以前の小田急の社章は「小」の文字の縦の線を線路の断面の「エ」のような形にし, 両側の点を円弧にして囲み, 円に縦棒が通っているような形と記憶している. 最近の車体にはMoebiusの帯のような図案の後に, Odakyuと書いてある. それを見ているうちに, またMoebiusの帯をプログラムで描いてみたくなった.

moebiusの帯では, Escherの版画にアリが歩いている有名な絵がある. 例えばこれ.
アリが動いている動画もあった.

それほど芸術的には出来ないが, とりあえず

のような書き方を考えた. まず上の図は, 平行四辺形ABCDが, くっきりと折り目をつけたmoebiusの帯である. 外周が六角形になる. 帯の長さ方向の辺ABの長さをaとし, 短い方の辺BCの長さをbとする. この平行四辺形を120度ずつ回転して3回書くわけだ. 回転の中心をOとし, 辺ABの中心HからOまでの長さをcとする. またOHとCDの交点をG. DGの長さをd, OGの長さをfとする.

d=(a-b)/2 c=(a/2+b)tan 30 f=d tan 30

である. 従ってOを原点とすれば, dだけ左, fだけ下のDへ行き, b/2だけ左, c-fだけ下へ移動してA, aだけ右へ移動してB, b/2だけ右, c-fだけ上へ移動してC, そして線を閉じる.

d neg f neg moveto %D
b -2 div f c sub rlineto %A
a 0 rlineto %B
b 2 div c f sub rlineto %D
closepath stroke

で描ける. このサブルーチンを例えばpと定義すると, p 120 rotate p 120 rotate p 120 rotate でくっきり線のmoebiusの帯が出来る.

でもやはりゆるやかに曲がった帯が描きたい. しかしそう大変でもないことが分かる. 上の図で, A,B,Cの角を円弧にすればよい. PostScriptの関数arcは円弧の中心のx,y座標, 円の半径r, 反時計まわりに中心から見た出発の角度と到着の角度をパラメータにし, 前に描き終った点から, この出発点までを直線で結び, その後に到着点までの円弧を描いてくれる. 時計回りにしたければarcnを使う.

上のプログラムでは rlineto で相対的な位置までの直線を描いたが, 今度は, translateを使い, 座標をA,B,Cに移動しながら描くことにする.

d neg f neg translate 0 0 moveto
b -2 div f c sub translate e r r 150 270 arc
a 0 translate e neg r r 270 330 arc
b 2 div c f sub translate e neg r r 330 270 arcn
closepath stroke a neg 0 translate d f translate} def

最初の行は, Dへ原点を移し, 0,0へペンを置いた.
次の行は, Aへ原点を移し, e,rを中心, 半径rで150度から270度まで円弧を描いた.
次の行は, Bへ原点を移し, -e,rを中心, 半径rで270度から330度まで円弧を描いた.
次の行は, Cへ原点を移し, -e,rを中心, 半径rで330度から270度まで時計まわりに円弧を描いた.
次の行のclosepathで0,0へ線を引き, 続く2つのtranslateで原点をOへ戻している.

最後にtranslateで戻す代りに, 描画環境をスタックに保存してくれる, gsaveとgrestoreを使う方が簡単であろう.