うしブログ

うしブログ

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

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

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

直線を、楕円の接線に吸い付かせる

課題

自由な点オブジェクトA,B,C,D,E および

楕円c=Ellipse(A, B, C)と、直線f=Line(D, E)がある。

下図のように、直線を動かして、楕円に近づけていって、直線が楕円に接する位置付近に来たときに、接線に吸い付くような挙動を実現するには、どうすればよいか。

f:id:usiblog:20201012183218g:plain

解答例

①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)

サンプル

https://www.geogebra.org/m/fdsf69vd