直線を、楕円の接線に吸い付かせる
課題
自由な点オブジェクトA,B,C,D,E および
楕円c=Ellipse(A, B, C)と、直線f=Line(D, E)がある。
下図のように、直線を動かして、楕円に近づけていって、直線が楕円に接する位置付近に来たときに、接線に吸い付くような挙動を実現するには、どうすればよいか。
解答例
①Dを動かしたときの処理
DのOn Update スクリプトとして、以下を記述する。
UpdateConstruction()
If(Distance(D,ClosestPoint({Tangent(f, c)}, D))<0.2,SetValue(D,ClosestPoint({Tangent(E, c)}, D)))
②Eを動かしたときの処理
EのOn Update スクリプトとして、以下を記述する。
UpdateConstruction()
If(Distance(E,ClosestPoint({Tangent(f, c)}, E))<0.2,SetValue(E,ClosestPoint({Tangent(D, c)}, E)))
③直線を動かしたときの処理
fを動かすと、同時にE,Fも動くので、上記E,FのOn Update スクリプトが発動してしまう。これは、直線をドラッグ(つまり平行移動)して、傾きを変えずに楕円に外接させる挙動を実現するうえでの障害になる。そこで、fのOn Update ハンドラにスクリプトを記述するのではなく、
g = CopyFreeObject(f)
で、自由な直線オブジェクトgを作成しておき、gに適宜On Update スクリプトを記述していく(fは非表示にしておく)ことにする。
gのOn Update スクリプトとして、以下を記述する。
Execute({"SetValue(D,ClosestPoint(g,D))","SetValue(E,ClosestPoint(g,E))"})
UpdateConstruction()
If(Distance(D,ClosestPoint({Tangent(f, c)}, D))<0.2,Execute({"SetValue(g,Line(ClosestPoint({Tangent(f, c)}, D),g))","SetValue(D,ClosestPoint(g,D))","SetValue(E,ClosestPoint(g,E))"}))
1行目:fをgに揃える。なお、これによってD,E,fの状態が更新されても、D,E,fのOn Updateスクリプトは発動しない。これは、On Updateスクリプトによって更新されたオブジェクトのOn Updateスクリプトは発動しない、というGeoGebraの仕様による。
2行目:1行目を適用した後の状態を前提に、次以降の行を記述するための処理。
3行目:吸い付き処理。
fのOn Update スクリプトとして、以下を記述する。
SetValue(g,f)