壁反射
Last-modified: 2019-01-27 (日) 03:16:01 (1518d)
StarLogoではタートルが前に進むことを繰り返すだけで、タートル の直線運動を表現できます。 これは、とても自然な表現なのですが、適当な縦横の境界(壁)を 設定して、タートルがそこを通り抜けずに「跳ね返る(反射)」する ような動作を表現するにはどうしたらいいでしょうか。 じっくり考えればだれでもわかることだと思いますが、このTipsでは それを紹介します。 タートルの前進 †タートルの前進は単にfd命令を出すだけです。1 だけ進みたければ fd 1 と書きます。このとき、タートルが向いている方向に対して1進み ますから、実際にはタートルのx方向とy方向の傾きに対して x方向にdx、y方向にdyだけ 位置を移動しています。StarLogoではこの名前(dx, dy)で値を参照 することができます。 つまり、右側をまっすぐ向いている場合にはdx=1、dy=0という値になっています。 タートルを拘束する境界の定義 †定義、といっても、単純で、タートルの行動範囲を限定する四角形 を決めるということです。これには4角形のそれぞれの辺に対応する 4つの値(xmin, xmax, ymin, ymax)を決めるということです。 タートルの位置(xcor, ycor)は次の範囲に行動を限定されます。 xmin <= xcor <= xmax ymin <= ycor <= ymax 境界で跳ね返るようにする †StarLogoでは、パッチの境界について自動的に処理しています。それは パッチの右側と左側、上側と下側の境界を「接続」した様に タートルを行動させます。 今回設定した境界にきたら、接続ではなくて、「反射」をさせます。 普通の運動の計算では、速度ベクトル(vx, vy)の符号を変えることでそれ を実現します。つまり、 xcor < xmin なら (vx, vy)を(-vx, vy)にする xcor > xmax なら (vx, vy)を(-vx, vy)にする ycor < ymin なら (vx, vy)を(vx, -vy)にする ycor > ymax なら (vy, vy)を(vx, -vy)にする といったように。 StarLogoでは、タートルの方向について、dx, dyで参照はできる ものの、それを書き換えることはできないので、タートルの方向を 指定する1つの方法であるheading(タートルの向きを表す上が0右 が90、下方向が180など)に角度を設定する方法を利用することに してみます。 タートルの方向を角度で表したとき、その角度angleは、dx, dyからも 計算できます。それは、atan関数(アークタンジェント:逆正接)を 利用して、次のようにします。 angle = atan(dx, dy) ※ここで、通常の数学ではatan(dy, dx)とするのですが、それは、x軸 右側が角度0で、かつ左周りが正なのに対して、タートルグラフィックス では、y軸上側が角度0で、かつ、右回りが正である、という事情により ます。 それで、反射のための規則を作ると、 xcor < xmin なら headingの値を atan(-dx, dy)にする xcor > xmax なら headingの値を atan(-dx, dy)にする ycor < ymin なら headingの値を atan(dx, -dy)にする ycor > ymax なら headingの値を atan(dx, -dy)にする というわけです。 手続きcheck-boundary †これを実際にStarLogoの手続きcheck-boundaryと して定義してみると、次のようになります。 if (ycor < ymin) [ sety ymin seth (atan dx (-1.0 * dy)) ] if (ycor > ymax)[ sety ymax seth (atan dx (-1.0 * dy)) ] if (xcor < xmin) [ setx xmin seth (atan (-1.0 * dx) dy) ] if (xcor > xmax)[ setx xmax seth (atan (-1.0 * dx) dy) ] 「seth」は 「set heading」の省略形です。また、sethの前に、座標を境界値に 強制設定していますが、これはちょっとしたテクニックです。 サンプル †実例としてサンプルを作りましたので乗せておきます。 ひとまず、Web Version(アプレット)で確認できますが、ソースの解説も多少必要かもしれない ので、それはこれから書きます。
Counter: 444,
today: 1,
yesterday: 0
|