Sample8
to polygon :side.size :poly
local "pangle
make "pangle (/ 360 :poly)
repeat :poly [
forward :side.size
right :pangle
]
end
to sample8
for "i 3 12 [polygon 50 i]
end
Sample9
to newpoly :diameter :poly
(local
"pangle "radius "center
"oldxy "newxy
)
make "pangle (/ 360 :poly)
make "radius (/ :diameter 2)
make "center getxy
penup
repeat :poly [
forward :radius
make "oldxy getxy
setxy :center
right :pangle
forward :radius
make "newxy getxy
setxy :oldxy
pendown
setxy :newxy
penup
setxy :center
]
pendown
end
to sample9
for "i 3 12 [newpoly 200 i]
end
sample8とsample9は、どちらも正多角形を描いています。どう違うでしょうか?
sample8は辺の長さを決めてから、そしてsample9は、多角形に外接する円の直径を決めてから描いています。
どちらが良いかは、必要とするプログラムでケースバイケースでしょう。
単純な手続きの、sample8の方が判りやすいと思います。それに較べたら、sample9は位置を行きつ戻りつを、繰り返して多角形を描いて少々見苦しいですね。
どちらの手続きも、引数polyに大きな数値を与えれば、どんどん円形になっていきます。
Circle
to circle :radius.x :radius.y
(local
"pangle "step "loop "center "head
)
(local
"po.x "po.y "po.xx "po.yy
)
name 4 "step
make "pangle 0.0
make "loop (+ / 360 :step 1)
make "center getxy
make "head heading
penup
repeat :loop [
make "po.x (* :radius.x cos :pangle)
make "po.y (* :radius.y sin :pangle)
make "po.xx (- * :po.x cos :head (* :po.y sin :head))
make "po.yy (+ * :po.x sin :head (* :po.y cos :head))
make "po.xx (+ :po.xx item 1 :center)
make "po.yy (+ :po.yy item 2 :center)
setxy sentence :po.xx :po.yy
pendown
make "pangle (+ :pangle :step)
]
penup
setxy :center
pendown
end
円を描く手続きCircleを5回続けて描いてみました。
circle 100 100
repeat 4 [circle 50 100 rt 45]
Terrapin
Logoには、stampovalと言う円や楕円を描く手続きがちゃんと有ります。
しかし、傾きの有る楕円は描けません。そこで新たに円を描く手続きを作成しました。
これも、sample8やsample9と同じで正N角形を描いて、円形を近似しているに過ぎません。
残念ながらCircle手続きは、タートルグラフィックスでは無く数学のサイン・コサイン関数を使った単純な物です。
make "po.xx (- * :po.x cos :head (* :po.y sin :head))
make "po.yy (+ * :po.x sin :head (* :po.y cos
:head))
この部分で、半径で求められたXY座標を、タートルの傾きを基準にして円(楕円)を、傾けています。
Sample10
to divideangle :div :poly
(local
"current.xy
"current.head
"angle
"dist
)
make "current.xy getxy
make "current.head heading
penup
home
forward - 100 (/ 100 :div)
right / 360 :poly
forward / 100 :div
make "angle pangle
make "dist (/ pdist 100)
setxy :current.xy
setheading :current.head
output list (- 90 :angle) :dist
end
to sample10 :diameter :poly [:times 32] 2
local "divide
name 20 "divide
local "angledist
make "angledist divideangle :divide :poly
right / / 360 :poly 2
repeat :times [
newpoly :diameter :poly
make "diameter (* :diameter item 2 :angledist)
right (item 1 :angledist)
]
end
多角形手続newpolyの、応用です。
sample10 200 3
sample10 200 4
sample10 200 5
として実行していますので、同じサイズで辺の数が違うだけで、面白い図形になります。
内接する図形を20分の1づつしながら、繰り返して描画していきます。
divideangleは、少々手抜きな関数です。B-D
実際に計算せずに、内接する図形の角度とサイズを、pdistとpangleを使い事前にシミュレートさせています。
こんな事をしては、数学の先生に叱られそうだけど私は、もう学生では無いので構いませんね。:-)
|