2014年11月14日金曜日

KETpicで陰影をつけた立体図を作る

「陰影を付けた立体図のKETpicによる描画」という論文に書いてあるコードを使って図を作成してみました.論文の図が見辛かったので.


R=2;    //球の半径
Th0=60;Phi0=-20;//光のくる方向
Th=Th0/180*%pi;Phi=Phi0/180*%pi; //(theta=60, phi=-20)
Vd=[sin(Th)*cos(Phi),sin(Th)*sin(Phi),cos(Th)]; //光線の方向ベクトル
Ve=[1,0,0]; //視線の方向ベクトル
Shd=1; Shd0=0.2; Shd1=0.45; Shd2=0.35; Spw=2; //明度を計算する定数
K0=50; K1=100; //theta, phiの2方向の分割数
//thetaはx軸と動径のなす方向,phiはyz平面への正射影とy軸とのなす角を表す.

Dth=%pi/2/K0; Dph=2*%pi/K1; //分割された角度 dtheta, dphi

Openfile('shade3.tex'); Beginpicture('1cm');
Dth0=0; R0=R*sin(Dth0); // 初期値 theta_0=0, r_0=0
for j=1:K0,
    Dph0=0;Dth1=Dth0+Dth; R1=R*sin(Dth1);
        //phi_0=0, theta_1=theta_0+ dtheta, r_1=R sin theta_1
    P0=R0*[cos(Dph0),sin(Dph0)]; P1=R1*[cos(Dph0),sin(Dph0)];
    for k=1:K1,
        Dph1=Dph0+Dph;
        P2=R1*[cos(Dph1),sin(Dph1)]; P3=R0*[cos(Dph1),sin(Dph1)];
        G=Listplot(P0,P1,P2,P3,P0); //閉曲線を作成
        P0=P3; P1=P2; Dph0=Dph1;
        Vn=[cos(Dth0),sin(Dth0)*cos(Dph0),sin(Dth0)*sin(Dph0)]; 
        Kd=Dotprod(Vn,Vd); //Vnは球面の法線ベクトル 
        Vs=2*Kd*Vn-Vd; //Vsは反射光の方向ベクトル
        if Kd<0 then Kd=0; end
        Ks=Dotprod(Ve,Vs); if Ks<0 then Ks=0; end // Veは視線方向
        Mc=Shd0+Shd1*Kd+Shd2*Ks^Spw; //明度
        Mc=Shd*(1-Mc); //塗りつぶす濃さ
        Texcom('{\color[cmyk]{0,0,0,'+string(Mc)+'}'); //色指定(黒の濃さ)
        Shade(G,1); Drwline(G); //Gの内部と境界線を塗りつぶす
        Texcom('}');
    end
    R0=R1; Dth0=Dth1; //次のループのための初期設定
end
Endpicture(0);Closefile();

領域を微小領域に分割して,対応する微小曲面を塗りつぶすという方法を取ったもの.色の付け方はPhong shadingという技法を用いているそう.次のWikipediaの項目を参照.

2014年11月6日木曜日

真空中でのボーリング球と羽毛の落下実験

ここまで大規模にやると説得力がありすぎる.They came down exactly the same!