曲面

空間内に曲面を描くとき,3Dグラフィックスでは,ワイヤフレームモデルとサーフェスモデルの2つの描き方があります。球面でいうと,ワイヤフレームモデルは経線と緯線が描かれた地球儀のようなものです。サーフェスモデルの場合はレイトレーシングという方法を用いて,光が当たっているような表面を描きます。また,隠れている線を表示しない「陰線処理」も行います。

KeTCindyでは,陰線処理は行いますが,レイトレーシングは行いません。したがって,球面のサーフェスモデルでは単に円にしか見えないものになります。放物面なども同様です。しかも,サーフェスモデルでは,陰線処理が複雑になるため,描画に非常に時間がかかります。曲面によっては描画されるまで2分以上かかるものもあります。この問題を解決するために,Cコンパイラを起動して描く方法をサポートしています。Cコンパイラの環境を設定する方法は,付録の「ダウンロードとインストール」を参照してください。以下では,C言語(gcc)の環境があるものとして進めます。

曲面描画の手続き

曲面は Sf3data() で陰線処理のないワイヤフレームモデルが描かれます。およその形状はこれでわかりますが,きちんと陰線処理を行うには, Sfbdparadata(),Wireparadata(),Crvsfparadata()を使います。ただし,単にこれを使うだけでは曲面は描画できません。次のような描画手続が必要です。

(1) Startsurf() で陰線処理をした面描画の宣言をする。 (2) 描画関数でプロットデータを作る。 (3) ExeccmdC() で,C 言語を用いてまとめて描画する。

これで描けますが,描画後にスライダで視点を変えようとすると動きが遅くなります。そのために,スライダ上の点を選択したかどうかを判定する関数Isangle() を用意しています。角度スライダを選択しているときは true そうでないときは false を返します。

そこで,Drawスロットのページには次のようなひな形を作っておくのがよいでしょう。

Putaxes3d(5);

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

fd=["z=4-(x^2+y^2)","x=r*cos(t)","y=r*sin(t)",

"r=[0,2]","t=[0,2*pi]","e"];

if(Isangle(),

Sf3data("1",fd);

,

Startsurf();

Sfbdparadata("1",fd);

// Wireparadata("1","sfbd3d1",fd,12,12);

Crvsfparadata("1","ax3d","sfbd3d1",fd);

ExeccmdC("1");

);

fd が曲面の方程式です。下図左のような,座標軸を陰線処理した回転放物面が描かれます。 Wireparadata を有効にして, Crvsfparadata をコメント化すると,右のような陰線処理されたワイヤフレームモデルが表示されます。下のスライダで視点を変えている間は,陰線処理のないワイヤフレームモデルが表示されます。

 

曲面の切断

曲面を平面で切断する例として,円錐曲線の描画をします。曲面と平面の交線を求めるには,Sfcutparadatacdy() を使います。

Sfcutparadatacdy(name,equation,list,options)

equation は切断する平面の方程式,list は曲面の式です。

fd=[

"p",

"x=r*cos(t)","y=r*sin(t)","z=2*(2-r)",

"r=[0,2]","t=[0,2*pi]","e"

];

Startsurf();

Sfbdparadata("1",fd);

Sfcutparadatacdy("1","y+2*z=3",fd);

ExeccmdC("1");

これだけで,円錐を描き,断面の楕円を描くことができます。

 


断面を陰線処理するには,Sfcutparadatacdy() に “nodsip” オプションをつけて非表示にしておき,Crvsfparadata() で陰線処理して表示します。ここで,切断面は sfc1n13d です。

Startsurf();

Sfbdparadata("1",fd);

Sfcutparadatacdy("1","y+2*z=3",fd,[“nodisp”]);

Crvsfparadata("1","sfc1n13d","sfbd3d1",fd);

ExeccmdC("1");

この円錐は,底面が半径2の円,頂点が (0,0,4) ですので,平面の法線ベクトルを (0,2,1) にして,方程式を 2*y+z=2 にすれば断面は放物線になり,y=-1 にすれば双曲線になります。

次に断面のプロットデータを閉曲線になるように作り,色を塗ります。プロットデータ sfc1n13d を Paraptで画面上の座標に変換し,Listplot()で輪郭を描いてShadeで色塗りします。

Startsurf();

Sfbdparadata("1",fd);

Sfcutparadatacdy("1","y+2*z=3",fd,["nodisp"]);

ExeccmdC("1");

pd=apply(sfc1n13d,Parapt(#));

Listplot("1",pd);

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

次に,断面だけでなく,切断している面も表示するようにしましょう。切断面は法線ベクトルを使って表します。

Startsurf();

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

nv=[0,1,2]; // 法線ベクトル

Perpplane("B-C","A",nv,"put");

v1=B3d-A3d;

v2=C3d-A3d;

P1=A3d+3*v1+2*v2;

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

P3=A3d+(-3)*v1-4*v2;

P4=A3d+3*v1-4*v2;

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

Sfbdparadata("1",fd);

Sfcutparadatacdy("1","y+2*z=3",fd,["nodisp"]);

ExeccmdC("1");

pd=apply(sfc1n13d,Parapt(#));

Listplot("1",pd);

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

切断面を変えたら,方程式に合わせて法線ベクトルを変えれば,放物線,双曲線も描けます。

nv=[0,2,1] nv=[0,1,0]

2*y+z=0 y=-1


<.戻る >