多角形内で点を自由に泳がせる方法
上記アプレットのように、点Pを、多角形poly1内で自由に泳がせる方法を紹介する。
前提として、オリジナルツール「Sides」(下記記事参照)のインポートが必要である。
多角形オブジェクトを用いて、頂点または辺のリストを返す - うしブログ
P = PointIn[poly1]
updater = 0
On Update スクリプトを発動するためのオブジェクト。後でアニメーションできるように、スライダーを作成しておく。増分は0.01くらいの、小さめの値がおすすめ。
Target = (0,0)
点Pが目指すべき目標。
v = (0,0)
速度ベクトル。
a = 0.005UnitVector[Vector[P, Target]] / (Distance[P, Target] + 10)
加速度ベクトル。スピードを変えるには、係数の0.005を調節する。
sensor = P ≟ ClosestPoint[Sides[poly1], P]
点Pがpoly1の辺にぶつかった場合に、trueを返すようなブーリアン。
wall = Element[RemoveUndefined[Zip[If[ClosestPoint[Sides[poly1], P] ≟ ClosestPoint[s, ClosestPoint[Sides[poly1], P]], s], s, Sides[poly1]]], 1]
点Pがぶつかった辺。
updaterのOn Update スクリプトとして、以下を記述する。
SetValue[v,(v+a)*0.99]
SetValue[P,Translate[P,v]]
If[sensor==true,SetValue[v,Reflect[v,wall]]]
If[Distance[P,Target]<1,SetValue[Target,RandomPointIn[poly1]]]
1行目:速度ベクトルvに、加速度ベクトルaの値を加算する。0.99は摩擦のつもりである。
2行目:点Pを、速度ベクトルvに応じて動かす。
3行目:点Pがpoly1の辺にぶつかったとき、速度ベクトルvを辺の鏡映に変換する。これによって、点Pが跳ね返る動きを実現している。
4行目:点Pが目標Targetに近づいたとき、Targetを、poly1内のランダムな位置に置き直す。これで、点Pがpoly1内を自由に泳ぐ動きを実現している。