- 2点の前後に延長する長さを指定する。
- 描画開始点と終了点のX座標を指定する。
2点の前後に延長する長さを指定
通過2点から角度を求めて、
始点からはその角度の反対方向に、
終点からはその角度方向に指定の長さの線分を引けばいい。
tt = Turtle ! create penup 1 linewidth (blue) linecolor.
tt:drawExpandedL = [ | ts te length ; x1 y1 x2 y2 angle |
x1 = ts!xPosition?. y1 = ts!yPosition?.
x2 = te!xPosition?. y2 = te!yPosition?.
[x2 == x1] ! then [
[ y2 > y1 ] ! then [ angle = 90 ] else [ angle = 270 ] execute ]
else [
angle = atan( (y2 - y1) / (x2 - x1)).
[ x2 < x1 ] ! then [ angle = angle+180] execute ]
execute.
self ! penup (x1) (y1) moveto (angle) direction 180 leftturn.
self ! pendown (length) forward.
self ! penup (x1) (y1) moveto.
self ! pendown (x2) (y2) moveto.
self ! (angle) direction (length) forward penup.
self ! 0 direction (x1) (y1+5) moveto pendown 5 circle.
self ! penup (x2) (y2+5) moveto pendown 5 circle penup.
].
tx = Turtle ! create hide.
ty = Turtle ! create hide.
tx ! 0 0 moveto.
ty ! 100 100 moveto.
tt ! (tx) (ty) 100 drawExpandedL makefigure.
tt ! hide.
始点終点がわかるように小丸を描いている。
角度は逆正接関数(atan)で求められる。
逆正接関数は、値域が -90 ~ +90 で始点/終点の反転に対して同値になるので、
始点位置と終点位置のX座標の大小に応じて 180 を加える必要がある。
また、Y座標が同じ場合にはエラーになってしまうので、
Y座標の大小に応じて90または270を与えるようにする。
描画開始点と終了点のX座標を指定
2点間の傾きを求めて、
その傾きから描画開始点、終了点各々のY座標を求めて、
描画開始点と終了点の間に直線を描く。
一次関数のグラフを描く感じ。
tt = Turtle ! create penup 1 linewidth (blue) linecolor.
tt:drawExpandedX = [ | ts te xstart xend length ;
x1 y1 x2 y2 ystart yend slope |
x1 = ts!xPosition?. y1 = ts!yPosition?.
x2 = te!xPosition?. y2 = te!yPosition?.
slope = (y2 - y1) / (x2 - x1).
ystart = (slope)*(xstart-x1) + y1.
yend = (slope)*(xend-x1) + y1.
self ! penup (xstart) (ystart) moveto.
self ! pendown (xend) (yend) moveto.
self ! 180 leftturn pendown (length) forward.
self ! penup (sx) (sy) moveto.
self ! pendown (ex) (ey) moveto penup.
self ! 0 direction (x1) (y1+5) moveto pendown 5 circle.
self ! penup (x2) (y2+5) moveto pendown 5 circle.
].
tx = Turtle ! create hide.
ty = Turtle ! create hide.
tx ! 0 0 moveto.
ty ! 100 100 moveto.
tt ! (tx) (ty) -50 150 drawExpandedX makefigure.
tt ! hide.
これも始点終点のX座標が同じ場合にエラーになるが、
そのそも描画開始X座標を指定する仕様上、垂直な線は描けないので気にしない。
まとめて描いてみる
両タイプの直線を、始点/終点を垂直方向に逆に動かしながら描いてみる。
tt = Turtle ! create penup 1 linewidth (blue) linecolor.
tt:drawExpandedL = [ | ts te length ; x1 y1 x2 y2 angle |
x1 = ts!xPosition?. y1 = ts!yPosition?.
x2 = te!xPosition?. y2 = te!yPosition?.
[x2 == x1] ! then [
[ y2 > y1 ] ! then [ angle = 90 ] else [ angle = 270 ] execute ]
else [
angle = atan( (y2 - y1) / (x2 - x1)).
[ x2 < x1 ] ! then [ angle = angle+180] execute ]
execute.
self ! penup (x1) (y1) moveto (angle) direction 180 leftturn.
self ! pendown (length) forward.
self ! penup (x1) (y1) moveto.
self ! pendown (x2) (y2) moveto.
self ! (angle) direction (length) forward penup.
self ! 0 direction (x1) (y1+5) moveto pendown 5 circle.
self ! penup (x2) (y2+5) moveto pendown 5 circle penup.
].
tt:drawExpandedX = [ | ts te xstart xend length ;
x1 y1 x2 y2 ystart yend slope |
x1 = ts!xPosition?. y1 = ts!yPosition?.
x2 = te!xPosition?. y2 = te!yPosition?.
slope = (y2 - y1) / (x2 - x1).
ystart = (slope)*(xstart-x1) + y1.
yend = (slope)*(xend-x1) + y1.
self ! penup (xstart) (ystart) moveto.
self ! pendown (xend) (yend) moveto.
self ! 180 leftturn pendown (length) forward.
self ! penup (sx) (sy) moveto.
self ! pendown (ex) (ey) moveto penup.
self ! 0 direction (x1) (y1+5) moveto pendown 5 circle.
self ! penup (x2) (y2+5) moveto pendown 5 circle.
].
t1 = Turtle ! create hide.
t2 = Turtle ! create hide.
t1 ! -300 -200 moveto 90 direction.
t2 ! -100 200 moveto -90 direction.
[
tt ! (t1) (t2) 100 drawExpandedL.
t1 ! 10 forward.
t2 ! 10 forward.
] ! 41 repeat.
tt ! makeFigure.
tt ! (red) linecolor.
t1 ! 100 -200 moveto 90 direction.
t2 ! 300 200 moveto -90 direction.
[
tt ! (t1) (t2) 50 350 drawExpandedX.
t1 ! 10 forward.
t2 ! 10 forward.
] ! 41 repeat.
tt ! makeFigure.
tt ! hide.
左は延長長さ固定型、右は描画X座標固定型。
描画X座標固定型が開始/終了点の横位置が揃うのに対して、
延長長さ固定型では傾きに応じて開始/終了点の横位置が変わるのがわかる。


0 件のコメント:
コメントを投稿