- 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 件のコメント:
コメントを投稿