2013年3月3日日曜日

[ドリトル] 直線延長

指定した2点を通る直線を引く。
  • 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 件のコメント:

コメントを投稿