うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

多角形内で点を自由に泳がせる方法

多角形内で点を自由に泳がせる – GeoGebra

 

上記アプレットのように、点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内を自由に泳ぐ動きを実現している。