空間図形のハッチング

Last modified: 2018 年 12 月 30 日 03 時

空間図形にハッチングし、累次積分の図示を再現する

主な使用関数: Arrowdata, Embed, Hatchdata, Sfbdparadata, Skeletonparadata, Spacecurve, Spaceline, Xyzax3data.

空間図形のハッチング 空間図形のハッチング

関数のグラフの描画

輪郭線 次の重積分の累次積分を図示します: \begin{align*} \iint_K ye^{xy}\,dxdy,\quad K=[0,1]\times [0,1] \end{align*} まずは、関数 $z=ye^{xy}$ のプロットデータfdを用意し、輪郭線outline,O1,O2を計算します。また、座標軸のプロットデータとしてaxisを用意します。各コマンドの詳細は、sample:曲面の陰線処理を参照してください。

xmin=0;
xmax=1;
ymin=0;
ymax=1;

Setangle(70,-60);
Setwindow([-0.5,2], [-1,3]);

function f=f(x,y); f=y*exp(x*y); endfunction
function F=F(x,y); F=[x, y, y*exp(x*y)]; endfunction

fd=list('z=f(x,y)', 'x=[xmin,xmax]', 'y=[ymin,ymax]', 'ewsn');
outline=Sfbdparadata(fd,100);  // 輪郭線

axis=Xyzax3data('x=[0,2]', 'y=[0,2]', 'z=[0,2]');  // 座標軸

O1=Spaceline([F(xmax,ymax)], [xmax,ymax,0], [xmax,ymin,0]);  // 輪郭線
O2=Spaceline([xmax,ymax,0], [xmin,ymax,0], [F(xmin,ymax)]);  // 輪郭線

Windisp(Projpara(outline, axis, O1, O2));

輪郭線 x=0.5のところでグラフをスライスし、できた切り口にハッチングをします。

まずは、その切り口のプロットデータを計算しましょう。切り口の(陰線処理をしていない)輪郭線がXSliceになります。これは、折れ線部分Lxと曲線部分CxよりなるリストXSlice=list(Lx,Cx)です。

x0=0.5;
Lx=Spaceline([F(x0,ymin)], [x0,ymax,0], [F(x0,ymax)]);
Cx=Spacecurve('F(x0,t)','t=[ymin,ymax]');
XSlice=list(Lx,Cx);  // 切り口の輪郭線

//Windisp(Projpara(XSlice, outline));

[このページのトップへ]

ハッチング

前項で描いた切り口にハッチングを施します。sample:角記号の応用編で角記号を空間に埋め込んだ方法と同じ要領です。すなわち、切り口と同じ平面図形にハッチングしてから、それを空間に埋め込みます。

切り口と同じ図形を平面に描いたものがlist(pL,pC)となります。この図形をハッチングしたデータがpH=Hatchdata('i',list(pL,pC),135,0.8)により得られます (参考: sample:領域のハッチング)。写像 $\textrm{Em}:(y,z)\mapsto (x_0,y,z)$ により空間に埋め込んだハッチングのプロットデータを得ることができます: XHatch=Embed(pH,Em)

pL=Listplot([ymin,f(x0,ymin)], [ymin,0], [ymax,0], [ymax,f(x0,ymax)]);
pC=Plotdata('f(x0,y)', 'y=[ymin,ymax]');
pH=Hatchdata('i', list(pL, pC), 135, 0.8);
function Em=Em(y,z)
  Em=[x0,y,z];
endfunction
XHatch=Embed(pH, Em);

Windisp(Projpara(XHatch));

ハッチングの埋め込み
[このページのトップへ]

陰線処理

先ほど得られたハッチングや切り口、座標軸のプロットデータを陰線処理します。sample:空間曲線の描画と同様で、今回の場合は、関数のグラフの輪郭線のうち、O1,O2は破線で描く予定なので、陰線処理は行わないものとします。また、切り口XSliceには陰線処理を行わないものとします。

ハッチングXHatchの上に、関数のグラフの輪郭線outlineと重なるので、陰線処理を施します(実際には、x=0.5のときは輪郭線は重ならない)。座標軸axisの上に、ハッチングXHatchが重なるので、これも陰線処理を施します。

sXHatch=Skeletonparadata(XHatch, list(outline), 0.4);
sXaxis=Skeletonparadata(axis, list(XHatch), 0.2);

Windisp(Projpara(outline, XSlice, O1, O2), sXaxis, sXHatch);

[このページのトップへ]

矢印の書き込み

写像 $\textrm{incZ}:(x,y)\mapsto (x,y,0)$ を定義し、これにより、平面の矢じりAxを空間に埋め込みます: XArrow=Embed(Ax,incZ)。また、Lx=Spaceline([xmin,My,0],[xmax,My,0])により、矢の棒の部分のプロットデータも用意しておきます。

function incZ=incZ(x,y)
  incZ=[x,y,0];
endfunction
Mx=(xmin+xmax)/2;
My=(ymin+ymax)/2;
Ax=Arrowdata([xmin,My], [xmax,My]);
//Ay=Arrowdata([Mx,ymin], [Mx,ymax]);
XArrow=Embed(Ax,incZ);
//YArrow=Embed(Ay,incZ);
Lx=Spaceline([xmin,My,0], [xmax,My,0]);
//Ly=Spaceline([Mx,ymin,0], [Mx,ymax,0]);

[このページのトップへ]

ソースコード

scilabファイル(.sce)のダウンロード
tic();

xmin=0;
xmax=1;
ymin=0;
ymax=1;

Setangle(70,-60);
Setwindow([-0.5,2], [-1,3]);

function f=f(x,y); f=y*exp(x*y); endfunction
function F=F(x,y); F=[x, y, y*exp(x*y)]; endfunction

fd=list('z=f(x,y)', 'x=[xmin,xmax]', 'y=[ymin,ymax]', 'ewsn');
outline=Sfbdparadata(fd,100);  // 輪郭線

axis=Xyzax3data('x=[0,2]', 'y=[0,2]', 'z=[0,2]');  // 座標軸

O1=Spaceline([F(xmax,ymax)], [xmax,ymax,0], [xmax,ymin,0]);  // 輪郭線
O2=Spaceline([xmax,ymax,0], [xmin,ymax,0], [F(xmin,ymax)]);  // 輪郭線

Windisp(Projpara(outline, axis, O1, O2));


x0=0.5;
Lx=Spaceline([F(x0,ymin)], [x0,ymax,0], [F(x0,ymax)]);
Cx=Spacecurve('F(x0,t)','t=[ymin,ymax]');
XSlice=list(Lx,Cx);  // 切り口の輪郭線

//Windisp(Projpara(XSlice, outline));

pL=Listplot([ymin,f(x0,ymin)], [ymin,0], [ymax,0], [ymax,f(x0,ymax)]);
pC=Plotdata('f(x0,y)', 'y=[ymin,ymax]');
pH=Hatchdata('i', list(pL, pC), 135, 0.8);
function Em=Em(y,z)
  Em=[x0,y,z];
endfunction
XHatch=Embed(pH, Em);

Windisp(Projpara(XHatch));

sXHatch=Skeletonparadata(XHatch, list(outline), 0.4);
sXaxis=Skeletonparadata(axis, list(XHatch), 0.2);

Windisp(Projpara(outline, XSlice, O1, O2), sXaxis, sXHatch);


y0=0.6;
Ly=Spaceline([F(xmin,y0)], [xmin,y0,0], [xmax,y0,0], [F(xmax,y0)]);
Cy=Spacecurve('F(t,y0)','t=[xmin,xmax]');
//sCy=Crv3onsfparadata(Cy, outline, fd);
YSlice=list(Ly,Cy);

//Windisp(Projpara(YSlice, outline));

pL=Listplot([xmin,f(xmin,y0)], [xmin,0], [xmax,0], [xmax,f(xmax,y0)]);
pC=Plotdata('f(x,y0)','x=[xmin,xmax]');
pH=Hatchdata('i',list(pL, pC),135,0.8);
function Em=Em(x,z); Em=[x,y0,z]; endfunction
YHatch=Embed(pH,Em);

//Windisp(Projpara(YHatch));

sYHatch=Skeletonparadata(YHatch, list(outline), 0.4);
sYaxis=Skeletonparadata(axis, list(YHatch), 0.2);

Windisp(Projpara(outline, YSlice, O1, O2), sYaxis, sYHatch);


function incZ=incZ(x,y)
  incZ=[x,y,0];
endfunction
Mx=(xmin+xmax)/2;
My=(ymin+ymax)/2;
Ax=Arrowdata([xmin,My], [xmax,My]);
Ay=Arrowdata([Mx,ymin], [Mx,ymax]);
XArrow=Embed(Ax,incZ);
YArrow=Embed(Ay,incZ);
Lx=Spaceline([xmin,My,0], [xmax,My,0]);
Ly=Spaceline([Mx,ymin,0], [Mx,ymax,0]);


Openfile('tex/multiple_integral_sampleX.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline, O1), 1.2);
Drwline(Projpara(XSlice), sXHatch, 0.5);
Drwline(sXaxis, 0.7);
Drwline(Projpara(Lx, XArrow), 0.8);
Xyzaxparaname(axis, 'x', ' ', 'z');
Setpen(.5);
Dashline(Projpara(O2), .6);
Expr(Projpara(F(xmax,ymax)), 'n2', '\displaystyle z=ye^{xy}');
Endpicture(0);
Closefile();


Openfile('tex/multiple_integral_sampleY.tex');
Beginpicture('1.5cm');
Drwline(Projpara(outline, O1), 1.2);
Drwline(Projpara(YSlice), sYHatch, 0.5);
Drwline(sYaxis, 0.7);
Drwline(Projpara(Ly, YArrow), 0.8);
Xyzaxparaname(axis, 'x', ' ', 'z');
Setpen(.5);
Dashline(Projpara(O2), .6);
Expr(Projpara(F(xmax,ymax)), 'n2', '\displaystyle z=ye^{xy}');
Endpicture(0);
Closefile();


T=toc();
minute=floor(T/60);
second=floor(T-60*minute);
disp(strcat([string(minute), ' minutes ', string(second), ' seconds']));

こちらの環境では、実行は40秒くらい。

[このページのトップへ]