Geogebraスキルアップ問題集(018解答)
問題
常に角BAC = 60°を保ちながら、点B、点Cをドラッグすると、それぞれ線分AB、線分ACの長さを自由に変えられるようにする。点Aをドラッグした場合は、図形全体が形を保って平行移動するようにする。
見本
解説
自由な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行の実行経過をスローモーションで再現すると、以下のようになります。
実行前。点Aと点Dは重なっている。
点Aを右にドラッグした瞬間。点AのOn Update スクリプトは、この状態を対象として実行される。
点Dは、ドラッグ前の点Aの位置を記録するためのオブジェクトとして利用している。
ドラッグ後の点Aを始点に、ベクトルVector[D,B]と等しいベクトルを描き(図の青い点線のベクトル)、その先端に点Bを移動させれば、点Aをドラッグしたのと同じ方向・同じ大きさだけ、点Bも移動することになる。これが点AのOn Update スクリプト1行目でやっていることである。
点AのOn Update スクリプト1行目の実行後。
2行目は、点Cについて同様の操作を行っている。
2行目実行後。
3行目実行後。点Dを新しい点Aの位置に揃えることで、次のドラッグ操作に備えている。