うしブログ

うしブログ

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

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

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

Geogebraスキルアップ問題集(018解答)

問題

常に角BAC = 60°を保ちながら、点B、点Cをドラッグすると、それぞれ線分AB、線分ACの長さを自由に変えられるようにする。点Aをドラッグした場合は、図形全体が形を保って平行移動するようにする。

f:id:usiblog:20161117032527g:plain

見本

GeoGebraファイル

解説

自由な3点A,B,Cを作成し、線分AB、線分ACを作成します。

点Bまたは点Cをドラッグした場合の設定

点Bをドラッグした場合には、点Cを、角BACが60°を保ち、かつ線分ACの現在の長さを保つように動かす必要があります。

まず、角BACが60°を保つように点Cを動かすには、点Aを中心に、点Bを反時計回りに60°回転したものの位置を、点Cの新たな位置とすれば良いです。そこで、点BのOn Update スクリプトに、SetValue[C,Rotate[B,60°,A]]と記述すれば良いことになります。

しかし、Rotate コマンドの性質上、点AとRotate[B,60°,A]との距離は、線分ABの距離と等しくなります。そのため、上記のコマンドのままでは、角BACは60°を維持するものの、線分ACの長さが保てません。

そこで、点Cの位置として望ましいのは、点Aを中心に、上記のRotate[B,60°,A]を、(線分ACの長さ) / (線分ABの長さ) 倍したものの位置ということになります。

そこで、点BのOn Update スクリプトに、以下を記述します。

SetValue[C,Dilate[Rotate[B,60°,A],Distance[A,C]/Distance[A,B],A]]

 

(注意)

上記のスクリプトを、下記のように、RotateとDilateの2行に分けて実行すると、線分ACの長さが保てず、うまくいきません。

SetValue[C,Rotate[B,60°,A]]

SetValue[C,Dilate[C,Distance[A,C]/Distance[A,B],A]]

なぜなら、2行目に登場するCは、1行目のSetValue コマンドによって位置が変更された後の点Cであり、すでに線分ACの長さが線分BCの長さに等しくなっているため、このあと2行目でDilate コマンドを実行しても、Distance[A,C]/Distance[A,B]の部分が1なので、結局線分ACの長さは線分BCの長さのままだからです。

 

CのOn Update スクリプトにも同様に、以下を記述します。

SetValue[B,Dilate[Rotate[C,-60°,A],Distance[A,B]/Distance[A,C],A]]

点Aをドラッグした場合の設定

点Aをドラッグした場合、それにあわせて点B、点Cが平行移動するようにするには、どのように設定すれば良いでしょうか。

まず、自由な点Dを作成し、入力バーに以下を入力して、点Dの位置を点Aに揃えておきます。

SetValue[D,A]

そして、点AのOn Update スクリプトに、以下を記述します。

SetValue[B,Translate[A,Vector[D,B]]]
SetValue[C,Translate[A,Vector[D,C]]]
SetValue[D,A]

1行目では、(更新後の)点Aを(点A更新前の)ベクトルVector[D,B]の方向に、そのベクトルの大きさだけ平行移動した位置に、点Bを移動させています。

同様に2行目では、(更新後の)点Aを(点A更新前の)ベクトルVector[D,C]の方向に、そのベクトルの大きさだけ平行移動した位置に、点Cを移動させています。

そして、3行目では、次の点Aの更新に備えて、点Dを最新の位置に更新しています。

上記3行の実行経過をスローモーションで再現すると、以下のようになります。

f:id:usiblog:20161117043414p:plain

実行前。点Aと点Dは重なっている。

 

f:id:usiblog:20161117043416p:plain

点Aを右にドラッグした瞬間。点AのOn Update スクリプトは、この状態を対象として実行される。

点Dは、ドラッグ前の点Aの位置を記録するためのオブジェクトとして利用している。

ドラッグ後の点Aを始点に、ベクトルVector[D,B]と等しいベクトルを描き(図の青い点線のベクトル)、その先端に点Bを移動させれば、点Aをドラッグしたのと同じ方向・同じ大きさだけ、点Bも移動することになる。これが点AのOn Update スクリプト1行目でやっていることである。

 

f:id:usiblog:20161117043417p:plain

点AのOn Update スクリプト1行目の実行後。

2行目は、点Cについて同様の操作を行っている。

 

f:id:usiblog:20161117043418p:plain

2行目実行後。

 

f:id:usiblog:20161117043420p:plain

3行目実行後。点Dを新しい点Aの位置に揃えることで、次のドラッグ操作に備えている。