点・直線・曲線・平面の描画

幾何点を作る

Cinderellaの「点を加える」ツールで点をとり,右側の対応する点をドラッグしてz座標を決めることができます。これで自由に動かせますが,ある位置に置こうとするとなかなかぴったりはできません。

Putpoint3d(["A",[0,-2,1]]);

のように座標を指定すればその位置に置けます。点Aは固定されます。オプションに”free” をつけると自由に動かせますが,もう一度プログラムを実行しなおしても指定した点にはなりません。指定した位置に置いてから自由に動かしたい場合は,一度 ”fix” をつけるか,オプションを外して実行した後,”free” をつけて再度実行します。

点名と座標はリストにします。複数の点を書き並べたリストにしてまとめて置くこともできます。

Putpoint3d(["A",[1,1,1], "B",[-1,0,2]]);

なお,幾何点A,Bがない場合は,このコマンドを実行するとA,Bを作成します。

また,幾何点を作らなくても,概念上の点は作れます。(後述)

幾何点の座標を取得する

点を作図してドラッグすると任意の位置に動かせますが,そのときの点の座標は,「点名3d」 で取得できます。点Aの位置はA3d です。

ここで,A3d は,変数であることに留意してください。そしてその値は,その名称の幾何点があれば,その点を選択したときにその座標が代入されますが,代入文で代入することもできます。その名称の幾何点がなくても,代入文で設定できます。

幾何点Aを作って,次のスクリプトを実行してみてください。

println("Aの座標は "+A3d);

点Aをドラッグすると,コンソールに表示される座標が変化します。

このコマンドの前に A3d=[1,1,1]; を入れてみると,Aをドラッグして位置が変わっても表示は変化しません。

println("Aの座標は "+A3d);

A3d=[1,1,1];

と後ろに置くと面白いことが起ります。点Aを選択すると(ドラッグしているときも選択状態です)値が変化し,点A以外のところをクリックして選択を解除すると[1,1,1]が表示されます。

これは,Cindyscriptの,「スロットによって実行タイミングが決まる」という特質のためです。

さらに,幾何点Aを消去してみてください。幾何点がなくても,点Aの座標 [1,1,1] が表示されます。つまり, A3d=[1,1,1]; とした時点で,概念としての点Aが存在することになります。

点を表示する

前述のように,幾何点の有無に関わらず, A3d=[1,1,1]; とすれば,概念上の点を作ることができます。幾何点でないので,見かけ上の大きさはありません。

空間座標で表された点を画面上に描くには, Drawpoint3d() または Pointdata3d() を使います。 Drawpoint3d() は,Cindyscriptの描画関数 draw() のように,画面上に緑の点を表示しますが,そのままではTeXのデータにはなりません。TeXのデータとして書き出すには,Pointdata3d()を使います。

たとえば,立方体の頂点を次のようにリストにします。

ptlist=[[1,0,0],[1,1,0],[0,1,0],[1,0,1],[1,1,1],[0,1,1],[0,0,1]];

これに対し,

Drawpoint3d(ptlist);

で,画面上に7つの点が表示されますが,Figure ボタンをクリックしても,できたPDFに点は表示されません。

Pointdata3d(“1”,ptlist,[“Size=3”]);

を追加すると,画面上の点は黒くなって点が書き出されます。

Drawpoint3d() は画面に表示するだけなので補助的な点を打つのに適しています。

線分を作る

点ができたら2点を結んで線分を作ります。Cinderellaの「線分を加える」ツールで線分を描くと,それがそのままプロットデータとなります。「線分を加える」ツールを使わずに線分を作るには,KeTCindyの関数 Spaceline() を使います。前項でやった立方体の頂点を結んでみましょう。一筆書きではできないので,経路を2つに分けます。たとえば,

pt1=[[1,0,1],[1,0,0],[1,1,0],[0,1,0],[0,1,1],[1,1,1],[1,1,0]];

pt2=[[1,1,1],[1,0,1],[0,0,1],[0,1,1]];

ptlist=pt1++pt2;

Pointdata3d("1",ptlist,["Size=2"]);

Spaceline("1",pt1);

Spaceline("2",pt2);

とします。 一筆書きではできないので,重複する点もありますが,表示上は問題ないでしょう。

曲線を描く

空間内における曲線です。方程式が媒介変数表示されているものとします。曲線は Spacecurve() で描きます。たとえば,

x=2cost,y=2sint,z=0.2t

は螺旋の媒介変数表示ですので

Spacecurve("1","[2*cos(t),2*sin(t),0.2*t]","t=[0,4*pi]",["Num=100"]);

で次のように螺旋が描けます。

平面を描く

空間内における平面ですが,実際に描くのは平面の一部です。たとえば,「点A(0,0,c) を通り, xy平面に平行な平面」というときは,次のような図を描くでしょう。4点でできる面です。

この図を描くには,矩形の4つの頂点を指定して線で結べばよいように思いますが,それだと折れ線になるだけなので面にはなりません。面にならないと,座標軸の陰線処理ができないので,次のような図にしかなりません。

A=[2,-2,1];

B=[2,2,1];

C=[-2,2,1];

D=[-2,-2,1];

Spaceline("1",[A,B,C,D,A]);

Letter([Parapt([0,0,1]),"w","c"]);

上の図との違いは,ABCDが「面としてのデータを持っている」かどうかという点です。そこで,コンピュータグラフィクスでは面のデータをどのように作るか,をまず知っておきましょう。

面は,3つ以上の点と,その順序を示すデータの2つから構成されます。今の例でいえば,点A,B,C,Dの座標リスト [A,B,C,D] と,順序を示す[1,2,3,4] というリストです。点の名前(座標)のリストと,この順序を対応させて,「面ABCD」が描かれます。順序を示すリストが,逆順の[4,3,2,1] であれば「面DCBA」となります。本来,この2つは別なものなのですが,KeTCindyではどちらでも図が描けますので,あまり気にしないようにしましょう。

KeTCindyでは,面が1つだけならば,点の座標リストを与えるだけで面データを作って表示する関数 VertexEdgeFace() を用意しています。これを使えば,陰線処理をする Nohiddenbyfaces() を使って座標軸の陰線処理ができて,さきほどの図が描けます。

Xyzax3data("","x=[-5,3]","y=[-5,3]","z=[-5,4]",["a"]);

A=[2,-2,1];

B=[2,2,1];

C=[-2,2,1];

D=[-2,-2,1];

VertexEdgeFace("1",[A,B,C,D]);

Nohiddenbyfaces("1","phf3d1");

Letter([Parapt([0,0,1]),"w","c"]);

さて,面は,3点や4点を指定して描く場合だけではありません。「点Aを通り、法線ベクトル に垂直な平面」がよく出てきます。これには,関数 Perpplane() を使います。

Perpplane(作る点,通る点の名前,法線ベクトル,option)

で,指定した点を通り法線ベクトルに垂直な平面上に基準点を 2 つとります。作成する 2 点は ”A-B” の形で名前を指定します。

option に ”put” を書くと,2 つの幾何点を作ります。option がない場合は幾何点は作らず, 無名の点のみを表示します。

たとえば, Perpplane("B-C","A",[1,1,1],"put"); とすると,点 A を通り,法線ベクトル (1,1,1) に垂直な平面上に点 B,C をとります。この2点は,Aを始点とする,互いに垂直な単位ベクトルの終点です。その状況の図を描きましょう。

Putpoint3d(["A",[1,1,1]]);

Perpplane("B-C","A",[1,1,1]);

Arrowdata([A,B]);

Arrowdata([A,C]);

Letter([A,"w","A",B,"e","B",C,"n","C"]);

ここで,Perpplane() の第2引数は点の名称を文字列で与えるので,Putpoint3d() で幾何点を作ってあります。

2つのベクトル [~] を使えば,この平面上の任意の位置が表現できて,次のように面を描くことができます。

Putpoint3d(["A",[1,1,1]]);

Perpplane("B-C","A",[1,1,1],"put");

Letter([A,"w","A"]);

v1=B3d-A3d;

v2=C3d-A3d;

P1=A3d+2*(v1+v2);

P2=A3d+2*(-v1+v2);

P3=A3d+2*(-v1-v2);

P4=A3d+2*(v1-v2);

VertexEdgeFace("1",[P1,P2,P3,P4]);

Nohiddenbyfaces("1","phf3d1");

Arrowdata([O,A],["do,1,2"]);

面データを作らず,折れ線で描いて座標軸を陰線処理することもできます。 VertexEdgeFace() と Nohiddenbyfaces() を次のスクリプトに変え,ベクトルOAを実線表示にします。

Spaceline("1",[P1,P2,P3,P4,P1]);

Skeletonparadata("1");

 

できた面に薄く色を塗ることも考えられます。P1〜P4の描画面上の座標を Parapt() で求め,Listplot() で平面の部分を描いて色を塗ります。

vt=apply([P1,P2,P3,P4,P1],Parapt(#));

Listplot("1",vt);

Shade(["sg1"],["Color=[0,0,0.2,0]"]);

平面上に垂線を下す

こんどは,先ほどとは逆に、面を描いておいて垂線を下します。よくあるパターンは,次のようなものです。

「3点 (2,0,0),(0,2,0),(0,0,2) を通る平面に原点から下した垂線の足をHとする。」

3点を通る平面は VertexEdgeFace() で描けるので,問題は垂線の足ですが,そのための関数 Perppt(点名,点,点リスト,option) が用意されています。Perpplane() と同様,第2は点の名前を文字列にし,第3引数も「リスト」となっていますが,”A-B-C” の形の文字列にします。そのため, Putpoint3d(); で幾何点を作ります。

Putpoint3d("A",[2,0,0]);

Putpoint3d("B",[0,2,0]);

Putpoint3d("C",[0,0,2]);

Perppt("H","O","A-B-C","put");

VertexEdgeFace("1",[A,B,C]);

Nohiddenbyfaces("1","phf3d1");

Arrowdata([O,H],["do,1,2"]);

Letter([A,"nw","A",B,"ne","B",C,"ne","C",H,"nw","H"]);

<.戻る >