Geogebraスキルアップ問題集(001解答)
001
Geogebraファイルの見本
基本的なアイデア
点Cが線分ABを押していないときには、線分AB(Segment[A,B])を表示させ、押しているときには非表示にして、かわりに曲線Spline[{A, C, B}, 3]を表示させている。
問題は、「点Cが線分ABを押しているとき」というのを、どのように表現するかである。
半直線の作成
点Cから線分ABと平行に、2本の半直線を引く(h, i)。hの作成方法を例にすると、まず点Cを通り線分ABに平行な直線Line[C, Segment[A,B]]を作成し、その直線上であって点Cより左側に点を作成し(点Fとする)、点Cから点Fを通るように引いた半直線Ray[C, F]をhとする。
点Aから線分ABと垂直に、また点Bから線分ABと垂直に、それぞれ2本の半直線を引く(j, e, k, f)。
半直線同士の交点の作成
半直線同士の交点L, M, H, Iを作成する。各点の定義は、以下の通りである。
L=Intersect[h, j]
M=Intersect[i, k]
H=Intersect[e, h]
I=Intersect[f, i]
曲線の表示条件
点L, M, H, Iは、Cの位置によって、定義されないこともある。
この図では、L, Mは定義されているが、H, Iは定義されていない。その理由は、hとe、およびiとfが交点をもたないからである。
この図では、H, Iは定義されているが、L, Mは定義されていない。その理由は、hとj、およびiとkが交点をもたないからである。
この図では、Mは定義されているが、L, H, Iは定義されていない。
「点Cが上から線分ABを押しているとき」には、Hが定義されていて、かつ、Iが定義されている。
「点Cが下から線分ABを押しているとき」には、Lが定義されていて、かつ、Mが定義されている。
したがって、曲線Spline[{A, C, B}, 3]の表示条件を、以下のようにすることが考えられる。
( IsDefined[H] ≟ true ∧ IsDefined[I] ≟ true )
∨
( IsDefined[L] ≟ true ∧ IsDefined[M] ≟ true )
しかしながら、表示条件をこのようにしてしまうと、点Cが線分ABの上から線分ABを通過する(押す)場合と、点Cが線分ABの横に回り込んで、線分ABの下にくる場合が区別されない。前者では曲線Spline[{A, C, B}, 3]を表示させたいが、後者では表示させたくない(かわりに線分ABを表示させたい)。点Cが線分ABを下から押す場合と、点Cが線分ABの下側から線分ABの横に回り込んで、線分ABの上側に行く場合との区別も、同様に必要となる。
そこで、「押す場合」と、「回り込む場合」とを区別する方法を考えなければならない。
真偽値の利用
2つの真偽値オブジェクトup, downを作成する。
点Cが線分ABの横を回り込んで、線分ABの上側に来たとき、up=true, down=falseとなるようにする。また、点Cが線分ABの横を回り込んで、線分ABの下側に来たとき、up=false, down=trueとなるようにする。
これを実現するためには、点CのOn Update スクリプトとして、以下の4行を記述する。
If[(IsDefined[L]==true∧IsDefined[M]==false)∨(IsDefined[L]==false∧IsDefined[M]==true),SetValue[up,true]]
If[(IsDefined[L]==true∧IsDefined[M]==false)∨(IsDefined[L]==false∧IsDefined[M]==true),SetValue[down,false]]
If[(IsDefined[H]==true∧IsDefined[I]==false)∨(IsDefined[H]==false∧IsDefined[I]==true),SetValue[up,false]]
If[(IsDefined[H]==true∧IsDefined[I]==false)∨(IsDefined[H]==false∧IsDefined[I]==true),SetValue[down,true]]
上2行は、「Cを動かして、LかMのどちらか一方のみが定義されているに至った場合には、upをtrueにし(1行目)、downをfalseにしなさい(2行目)」という命令である。点Cが線分ABの下側から上側に回り込む場合の命令である。
下2行は、「Cを動かして、HかIのどちらか一方のみが定義されているに至った場合には、upをfalseにし(3行目)、downをtrueにしなさい(4行目)」という命令である。点Cが線分ABの上側から下側に回り込む場合の命令である。
こうして、「押す場合」と「回り込む場合」の区別ができた。
すなわち、点Cが線分ABの上から線分ABを通過する(押す)場合は、up=true, down=falseのままであるが、点Cが線分ABの横に回り込んで、線分ABの下にくる場合には、up=false, down=trueに真偽値が変更され、両者が真偽値によって区別される(下から押す場合と、回り込んで上側に行く場合との区別についても同様である)。
曲線Spline[{A, C, B}, 3]の表示条件は、真偽値による区別を加味して、以下のように記述する。
( up ≟ true ∧ IsDefined[H] ≟ true ∧ IsDefined[I] ≟ true )
∨
( down ≟ true ∧ IsDefined[L] ≟ true ∧ IsDefined[M] ≟ true )
これによって、線分ABの上側から、線分の横を回り込んで、下側に行った場合(すなわちdown=trueの場合)に、曲線が表示されるのを防ぎ(1行目)、また線分ABの下側から、線分の横を回り込んで、上側に行った場合(すなわちup=trueの場合)にも、曲線が表示されるのを防いでいる。
線分ABの表示条件
線分ABは、曲線Spline[{A, C, B}, 3]が表示されない場合に表示したい。そのため、曲線Spline[{A, C, B}, 3]の表示条件を否定した論理式を、線分ABの表示条件とする。ド・モルガンの法則がたいへん役に立つ。
( up ≟ false ∨ IsDefined[H] ≟ false ∨ IsDefine
d[I] ≟ false )
∧
( down ≟ false ∨ IsDefined[L] ≟ false ∨ IsDefined[M] ≟ false )
仕上げ
仕上げとして、不要なオブジェクト(半直線、点L, M, H, I、真偽値チェックボックス)を非表示にすれば、完成である。
別解
上記のアプレットは、線分ABをドラッグして、点Cの横を通って、点Cの上側に持っていくと、線分ABは曲がってしまう。
これを克服するには、別解が必要になる。
別のアプローチで作成したアプレット