C02 三角形の折り目の問題

問題は

三角形の紙がある。次の条件を満たすすべての折り方をしたときに、折り目が付かない領域を求めよ。

    • 条件1 ある頂点Aを、三角形の内部の1点に重なるように折る

    • 条件2 そのとき、折り目は頂点Aの対辺と交差しない

です。「GeoGebra日本」の対応するページをごらんください。また解説もこのページにあります。

ここでは,このページを補う形でCinderellaで作図します。

まず,条件を満たすような折り方がどのようになるか作図しましょう。ちょっと考えればわかります。

次のようになりますね。

折ったとき,AG=DG,AF=FD なので,ADの垂直二等分線を引けばよいのです。

(ADの二等分線GFを引いた後,線分を上書きして二等分線を非表示にしています。)

補助線を消しておきます。

これで試行錯誤してみると,「GeoGebra日本」のページにある補題の意味がわかります。

領域1 領域2


領域3 領域4


一見すると,領域3は領域1に含まれるので,折り目の存在する領域は領域1でよさそうですが,三角形の形状によってそうはならないのです。次の図のように,三角形の形状によっては領域1の中には来れない場合があるのです。

そこで,「領域1 ∩ 領域3 は領域1か 領域3に一致」すると考えます。

領域2 ∩ 領域4 についても同様です。

さて,上の図は多角形ツールで色塗りをしましたが,「ここには来れない」部分は実際には色塗りをしないように,しかも,それがインタラクティブにできるようにしましょう。

もう一度,領域1と領域3の関係を見ると,共通部分と見るのではなく,場合分けをして考える方がよさそうです。(実際プログラムしてみると,その方が簡素にできます)

Bの二等分線とACの交点Kと,ACの中点Hの位置関係で場合分けします。また,このあとは領域の論理演算になるので,多角形で色塗りをするのではなく,「シェイプ」を使います。「シェイプ」は,領域の論理演算を行うことのできるもので,Cindyscriptに関数が用意されています。

まず,領域を定義します。

if(|A,K|<|A,H|,

shape1=polygon([A,B,K]); // 領域1 Bの二等分線A側

,

shape1=polygon([A,H,L]); // 領域3 ACの垂直二等分線A側

);

if(|A,M|<|A,N|,

shape2=polygon([A,C,M]); // 領域2 Cの二等分線A側

,

shape2=polygon([A,N,O]); // 領域4 ABの垂直二等分線A側

);

この2つの領域 shape1とshape2 の併合が,Aを折ったときの折れ線が存在する領域です。併合を求めるには,演算子++を用います。

domainA=shape1++shape2;

この領域を色塗りして表示するには,fill()を用います。

fill(domainA,color->[1,0.8,0]);

次の図のようになります。


同様にして,Bを折ったときと,Cを折ったときの領域を作ります。

if(|B,M|<|B,N|,

shape3=polygon([B,C,M]); // Cの二等分線B側

,

shape3=polygon([B,N,Q]); // ABの垂直二等分線B側

);

if(|B,R|<|B,S|,

shape4=polygon([B,A,R]); // Aの二等分線B側

,

shape4=polygon([B,S,T]); // BCの垂直二等分線B側

);

domainB=shape3++shape4;

if(|C,R|<|C,S|,

shape5=polygon([C,A,R]); // Aの二等分線C側

,

shape5=polygon([C,S,U]); // BCの垂直二等分線C側

);

if(|C,K|<|C,H|,

shape6=polygon([C,B,K]); // Bの二等分線C側

,

shape6=polygon([C,H,P]); // CAの垂直二等分線C側

);

domainC=shape5++shape6;

なお,それぞれ,直接関係しない線は非表示にしたり,点線にしたりしています。


最後に,この3つの領域の併合をとります。

alldomain=domainA++domainB++domainC;

fill() で表示するのは,この領域だけでよいので,ここまでにそれぞれ表示したものは,先頭に // を書いてコメント行にしておきましょう。

fill(alldomain,color->[1,0.8,0]);

これで解答図ができます。