うしブログ

うしブログ

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

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

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

On Update スクリプトによるオブジェクトの連動(平行移動・回転移動)

前提

点A、点Bを自由なオブジェクトとします。

点Aをドラッグして移動させると、それに連動して点Bも動くようにする方法を考えます。

なお、点Bをドラッグして移動しても、点Aは動かないことが条件です。

 

平行移動

方法1:Aを中心とする円上の点にBを合わせる

f:id:usiblog:20161120013541g:plain

数値オブジェクトrを作成する。

円R:Circle[A,r]を作成し、点C:Point[R]を作成する。

点Cは、円R上の点であり、点Aをドラッグすると、連動して平行移動する。これに点Bを合わせれば良い。

点AのOn Update スクリプトに、以下を記述する。

UpdateConstruction[ ]
SetValue[B,C]

点Bをドラッグしたときには、点Cが常に点Bと重なるように設定する。

そのため、点BのOn Update スクリプトに、以下を記述する。

SetValue[r,Distance[A,B]]
SetValue[C,B]

方法2:点A移動前のVector[A,B]にしたがって、移動後の点Aを平行移動した点の位置に、点Bの位置を揃える(移動前の点Aを別オブジェクトで表現する)

f:id:usiblog:20161120015847g:plain

自由な点オブジェクトCを作成する。

SetValue[C,A]を実行し、CをAに揃えておく。

ベクトルu:Vector[C,B]を作成し、点AのOn Update スクリプトに以下を記述する。

SetValue[B,Translate[A,u]]
SetValue[C,A]

方法3:点A移動後のVector[C,A]にしたがって、点Bを平行移動する

f:id:usiblog:20161120020854g:plain

自由な点オブジェクトCを作成する。

SetValue[C,A]を実行し、CをAに揃えておく。

ベクトルu:Vector[C,A]を作成し、点AのOn Update スクリプトに以下を記述する。

UpdateConstruction[ ]
SetValue[B,Translate[B,u]]
SetValue[C,A]

方法4:点A移動前のVector[A,B]にしたがって、移動後の点Aを平行移動した点の位置に、点Bの位置を揃える(移動前の点Aを別オブジェクトで表現しない)

f:id:usiblog:20161120022817g:plain

これが一番簡単です。

ベクトルu:Vector[A,B]を作成する。

点AのOn Update スクリプトに以下を記述する。

SetValue[B,Translate[A,u]]

 

回転移動(OA:OBを維持)

f:id:usiblog:20161120025256g:plain

点A移動前のAngle[A,O,B]にしたがって移動後の点Aを回転し、移動前の比率Distance[O,B]/Distance[O,A]にしたがって、点Oとの距離を調節した点の位置に、点Bの位置を揃える。

(手順)

角度α:Angle[A,O,B]を作成する。

数値a:Distance[O,A]、数値b:Distance[O,B]を作成する。

点AのOn Update スクリプトに、以下を記述する。

SetValue[B,Dilate[Rotate[A,α,O],b/a,O]] 

 

回転移動(OBを維持)

方法1

f:id:usiblog:20161120031447g:plain

数値オブジェクトαを作成する。

数値a:Distance[O,A]、数値b:Distance[O,B]を作成する。

点C:Dilate[Rotate[A, α, O], b / a, O]を作成する。点Cは、点Aをドラッグすると、それに連動してOCを維持しながら点Oを中心に回転移動する。

点AのOn Update スクリプトに以下を記述する。

UpdateConstruction[]
SetValue[B,C]

点BのOn Update スクリプトに以下を記述する。

SetValue[α,Angle[A,O,B]]
SetValue[C,B]

方法2

f:id:usiblog:20161120033921g:plain

自由な点オブジェクトCを作成する。

SetValue[C,A]を実行し、CをAに揃えておく。

角度α:Angle[C,O,A]を作成し、点AのOn Update スクリプトに以下を記述する。

UpdateConstruction[ ]
SetValue[B,Rotate[B,α,O]]
SetValue[C,A]

方法3

f:id:usiblog:20161120035731g:plain

自由な点オブジェクトCを作成する。

角度α:Angle[C,O,B]を作成する。

数値オブジェクトb:Distance[O,B]、c:Distance[O,C]を作成する。

点AのOn Update スクリプトに以下を記述する。

SetValue[B,Dilate[Rotate[A,α,O],b/Distance[O, A],O]]
SetValue[C,A]

 1行目にDistance[O, A]とある。この部分を、点Aに従属した数値オブジェクトa:Distance[O, A]を作成したうえで、aに置き換えた場合、点A移動前のOAの長さが参照されるため、OBの長さが維持できない。ここをDistance[O, A]と書けば、点A移動後のOAの長さが参照されるため、OBの長さを一定に維持することができる。微妙な違いではあるが、注意が必要である。

方法4

f:id:usiblog:20161120040946g:plain

最も簡単な方法である。

角度α:Angle[A,O,B]を作成する。

数値b:Distance[O,B]を作成する。

点AのOn Update スクリプトに、以下を記述する。

SetValue[B,Dilate[Rotate[A,α,O],b/Distance[O,A],O]]

上述の、OA:OBを維持した回転移動の方法と比べると、Dilateの比率の分母を、数値オブジェクトa:Distance[O,A]とするか、Distance[O,A]を直接記述するかの違いである。

前者は点A移動前のOAの長さであり、後者は点A移動後のOAの長さである。この違いで、OA:OBを維持するか、OBの長さを維持するかの違いが生まれる。