曲面上の曲線の描画
陰線処理された曲面上の曲線の描画と曲面のワイヤーフレーム表示の別法
主な使用関数: Crv3onsfHiddenData, Crv3onsfparadata, Sf3data, Sfbdparadata, Spacecurve.
曲面のプロットデータを得る記法をまとめると、次のようになる:
- グラフ型の曲面 $z=f(x,y)\;((x,y)\in[a,b]\times[c,d])$:
fd=list('z=f(x,y)','x=[a,b]','y=[c,d]','ewsn')
(cf. sample:曲面の陰線処理)- 領域上のグラフ型の曲面 $z=f(x(u,v),y(u,v))\;((u,v)\in[a,b]\times[c,d])$:
fd=list('z=f(x,y)','x=x(u,v)','y=y(u,v)','u=[a,b]','v=[c,d]','ewsn')
(cf. 本稿 — sample:曲面上の曲線の描画)- パラメータ付けされた曲面 $p(u,v)=(x(u,v), y(u,v), z(u,v))\;((u,v)\in[a,b]\times[c,d])$ :
fd=list('p','x=x(u,v)','y=y(u,v)','z=z(u,v)','u=[a,b]','v=[c,d]',' ')
(cf. sample:パラメータ付けされた曲面の描画)
曲面の描画
視点をSetangle(70,-65)で設定します (tips: 3次元のプロットの視点・投影方向)。曲面 \begin{align*} z=f(x,y)=x^2-y^2 \end{align*} を中心が原点、半径1の円で囲まれる領域上でプロットするには、
fd=list('z=x^2-y^2', 'x=r*cos(t)','y=r*sin(t)','r=[0,1]','t=[0,2*%pi]','e');
surface=Sf3data(fd,50,50,[50,70]);
とし、(陰線処理されていない) ワイヤーフレーム表示された曲面のデータsurfaceを得ます。また、輪郭線をoutline=Sfbdparadata(fd,100)で得ることができます (cf. sample:曲面の陰線処理)。
Setangle(70,-65);
Setwindow([-1.5,1.5], [-1.5,1.5]);
function f=f(x,y)
f=x^2-y^2;
endfunction
fd=list('z=f(x,y)', 'x=r*cos(t)', 'y=r*sin(t)',..
'r=[0,1]', 't=[0,2*%pi]', 'e');
surface=Sf3data(fd, 50, 50, [50,70]);
Windisp(Projpara(surface));
outline=Sfbdparadata(fd, 100);
上のように、fd=list('z=f(x,y)', 'x=x(u,v)','y=y(u,v)',uの範囲,vの範囲,境界の指定)とし、Sf3dataに通して、曲面 $z=f(x,y)$ のプロットデータを得られます。sample:曲面の陰線処理との違いは、x,yはパラメータ表示x=x(u,v),y=y(u,v)で指定できる点です。また、境界の指定は、ewsnから選んで指定します。今の場合、xy平面で円周が曲面の境界にあたるので、右図のように、境界'e'、すなわち、 $\{1\}\times\left[0,2\pi\right]$を指定します。
他の関数の詳細は、sample:曲面の陰線処理と同様です。
曲面上のArchimedesの螺旋
ここでは、Archimedesの螺旋 $r=K^{-1}\theta\;(K=8\pi)$ を曲面上にうつした曲線を考えてみましょう (冒頭右図)。
C=Spacecurve(...)により、曲面上の曲線Cを用意し、Crv=Crv3onsfparadata(C,outline,fd)によって、曲面による陰線処理をした空間曲線Crvを得られます。また、曲面により陰になった部分はhCrv=Crv3onsfHiddenData()で得られます:
K=8*%pi;
C=Spacecurve('[theta/K*cos(theta),..
theta/K*sin(theta),..
f(theta/K*cos(theta), theta/K*sin(theta))]',..
'theta=[0,8*%pi]', 'N=300');
Crv=Crv3onsfparadata(C, outline, fd);
hCrv=Crv3onsfHiddenData();
C=Spacecurve('[x(t),y(t),z(t)]','t=[a,b]','N=整数')で、空間曲線 $c(t)=(x(t),y(t),z(t))$ のプロットデータを得ることができます。N=整数のオプションで曲線の折れ線分割の点の数を指定できます (大きいほどなめらかに描画されます)。デフォルトはN=50で、省略可能になっています。
[このページのトップへ]
曲面のワイヤーフレーム表示
次に、この曲面のワイヤーフレーム表示を求めましょう (冒頭左図)。実は、sample:曲面の陰線処理と同様に、Wireparadata関数を使おうとすると、エラーが出ます (Scilab 5.5.1, KETpic 5.1.0)。おそらく、原点周りの計算が原因でしょう。ここでは、Crv3onsfparadataを利用して、お手製のワイヤーフレームを作ることにします。
for文において、原点を中心とし、半径がR=i/Nの円を曲面の関数 $f(x,y)=x^2-y^2$ で移し曲面上の曲線として、Crv3onsfparadataで陰線処理します。また、直線theta=2*%pi/M*iも同様に処理します。
N=8;
LCrv1=list();
for i=1:(N-1)
R=i/N;
tmp1=Spacecurve('[R*cos(t), R*sin(t), f(R*cos(t), R*sin(t))]',..
't=[0,2*%pi]', 'N=150');
LCrv1($+1)=Crv3onsfparadata(tmp1, outline, fd);
end
M=20;
LCrv2=list();
for i=1:M
theta=2*%pi/M*i;
tmp2=Spacecurve('[r*cos(theta),..
r*sin(theta),..
f(r*cos(theta), r*sin(theta))]',..
'r=[0,1]', 'N=150');
LCrv2($+1)=Crv3onsfparadata(tmp2, outline, fd);
end
Windisp(Projpara(LCrv1, LCrv2, outline));
[このページのトップへ]
TeXファイルの書き出し
現在のsceファイルのあるディレクトリの下のtexディレクトリにTeXファイルを書き出しします。
前者はワイヤーフレームの描画、後者は(陰線処理した) Archimedesの螺旋を描画したものです。
Openfile('tex/surface_sample2_1.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline), 1.5);
Drwline(Projpara(LCrv1, LCrv2), 0.5);
Endpicture(0);
Closefile();
Openfile('tex/surface_sample2_2.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline), 1.5);
Drwline(Projpara(Crv), 0.5);
Setpen(0.5);
Dashline(Projpara(hCrv), 0.4, 0.4);
Endpicture(0);
Closefile();
[このページのトップへ]
ソースコード
scilabファイル(.sce)のダウンロード
tic();
Setangle(70,-65);
Setwindow([-1.5,1.5], [-1.5,1.5]);
function f=f(x,y)
f=x^2-y^2;
endfunction
fd=list('z=f(x,y)', 'x=r*cos(t)', 'y=r*sin(t)',..
'r=[0,1]', 't=[0,2*%pi]', 'e');
surface=Sf3data(fd, 50, 50, [50,70]);
Windisp(Projpara(surface));
outline=Sfbdparadata(fd, 100);
K=8*%pi;
C=Spacecurve('[theta/K*cos(theta),..
theta/K*sin(theta),..
f(theta/K*cos(theta), theta/K*sin(theta))]',..
'theta=[0,8*%pi]', 'N=300');
Crv=Crv3onsfparadata(C, outline, fd);
hCrv=Crv3onsfHiddenData();
N=8;
LCrv1=list();
for i=1:(N-1)
R=i/N;
tmp1=Spacecurve('[R*cos(t), R*sin(t), f(R*cos(t), R*sin(t))]',..
't=[0,2*%pi]', 'N=150');
LCrv1($+1)=Crv3onsfparadata(tmp1, outline, fd);
end
M=20;
LCrv2=list();
for i=1:M
theta=2*%pi/M*i;
tmp2=Spacecurve('[r*cos(theta),..
r*sin(theta),..
f(r*cos(theta), r*sin(theta))]',..
'r=[0,1]', 'N=150');
LCrv2($+1)=Crv3onsfparadata(tmp2, outline, fd);
end
Windisp(Projpara(LCrv1, LCrv2, outline));
Openfile('tex/surface_sample2_1.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline), 1.5);
Drwline(Projpara(LCrv1, LCrv2), 0.5);
Endpicture(0);
Closefile();
Openfile('tex/surface_sample2_2.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline), 1.5);
Drwline(Projpara(Crv), 0.5);
Setpen(0.5);
Dashline(Projpara(hCrv), 0.4, 0.4);
Endpicture(0);
Closefile();
T=toc();
minute=floor(T/60);
second=floor(T-60*minute);
disp(strcat([string(minute), ' minutes ', string(second), ' seconds']));
[このページのトップへ]