2012年7月9日月曜日

[ドリトル] 衝突判定

Dolittleでは、Turtle と 図形との間で衝突判定ができる。
Turtleが他の図形と重なったと判定された時に、 collision命令(「衝突」命令)が実行される。

面白そうなので早速使ってみる。
どのくらいの範囲で衝突したとみなされるのか調べてみよう。

基本的な考え方は以下の通り。
  • ターゲットとなる図形を書く。ターゲットは20x20の正方形
  • Y座標を上から下へずらしながら、左から右へTurtleを動かし衝突するか調べる。
  • 最初に衝突したY座標と最後に衝突したY座標を表示する。
やってみよう。

t1 = Turtle ! create.
lblStartOfCollision = Label ! "start" create.
lblEndOfCollision = Label ! "end" create.

// create target.
t1 ! penup 100 back pendown 1 linewidth.
t1 ! 90 leftturn 10 forward 90 rightturn 20 forward.
t1 ! 90 rightturn 20 forward 90 rightturn 20 forward.
t1 ! 90 rightturn 10 forward 90 leftturn.
t1 ! makefigure (blue) paint.
t1 ! penup movetocenter.
collisioned = false.

t1:goUntilCollision = [ | y ; count | 
   collisioned = false.
   count = 0.
   [ (collisioned ! not) ! (count < 200) allTrue ] ! while [
     self ! 1 forward.
     count = count + 1.
   ] execute.
   [ collisioned ! (inCollision ! not) allTrue ] ! then [
      lblStartOfCollision ! (y) set.
      inCollision = true.
   ] execute.
   [ (collisioned ! not) ! (inCollision) allTrue ] ! then [
      lblEndOfCollision ! (y + 1) set.
      inCollision = false.
   ] execute.
   self ! penup movetocenter. 
].

t1:collision = [ collisioned = true. ].

// try to collision
inCollision = false.
[ | y |
  t1 ! penup 90 rightturn (50 - y) forward 90 leftturn pendown.
  t1 ! (50 - y) goUntilCollision.   
] ! 100 repeat.  

衝突判定命令はTurtleの移動とは独立して呼び出されるので、大域変数を使って移動を実行しているブロックに通知をしている。
で結果。
プラスマイナス23。思ったよりマージンがある。
図形の範囲が-10 から +10 なので 13 ポイントずつマージンがある感じ。 ターゲットサイズを半分の 10 (-5~+5) にしてみたところ結果はプラスマイナス18なので、確かにマージンが13ポイントずつあるようだ。

ついでにもう一つ。
ターゲットのサイズは20のままにして、線の太さを30にしてみる。

...
t1 ! penup 100 back pendown 30 linewidth.
...
突き抜けた。結果は線幅が 1 の時のプラスマイナス 23 と同じ。
つまり、図形そのものの座標で衝突判定が決まっていて、(線の太さなどで変わる)描画されている領域で判定されるわけではないということのようだ。

ついでにTurtleが描画するラインは、図形の下側に描画されることも分かった。
このあたりの描画順などは改めて見てみることにしよう。

なお、衝突判定は「Turtleを移動した結果(または図形側が移動した結果)」重なりが発生した場合に発生する。移動の始点と終点の間に障害物があった場合には衝突判定は発生しない。

やってみる。これまでは1ステップずつTurtleを動かしていたが、150ステップ一気に進めてみよう。
ターゲットまでの距離は 100 なので X 方向のマージンを見越しても余裕で飛び越える。

...
   [ (collisioned ! not) ! (count < 200) allTrue ] ! while [
     self ! 150 forward.
     count = count + 150.
   ] execute.
...
衝突しなかった。



Turtle は scala 命令で拡大縮小できるので、その影響を見てみる。
最初のプログラムで、カメを2倍にしてみる。

t1 = Turtle ! create.
t1 ! 2 scale.
マージン分が大きくなった。カメの大きさも影響しているようだ。
図形の範囲が-10 から +10 なので、マージンはプラスマイナス26。
最初のプラスマイナス13からちょうど倍になっていることがわかる。

t1 = Turtle ! create.
t1 ! 0.1 scale.
マージンがなくなった。
拡大率が0.06まではほぼ同じだが、0.05まで小さくすると衝突しなくなってしまう。
さらに小さくして、0.02まで来ると小さすぎて無効扱いになるのか元サイズに戻ってしまった。

t1 = Turtle ! create.
t1 ! 0.05 scale.



0 件のコメント:

コメントを投稿