スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Asymptoteで立体の輪郭を描く

最近、Asymptoteをいじっている。奥村先生の美文書作成入門で紹介されていたので試したところ、なかなか良さそうだったからだ。しかし、どうにもドキュメントが足りない。付属のドキュメントを読めば簡単な図は描けるようになるが、もっとやり込もうとするとリファレンスマニュアルが欲しくなる。ソースコードは割ときれいでコメントもついているのでそれを読めばいいのだが。

今回はこんな図を描いてみた:

polar.png
import three;
import solids;

size(500);

currentprojection=orthographic(5,4,2,center=true);
currentpen=black+2.0;

// 中心O,半径1の球
revolution s = sphere(O,1);

// 球(回転体)の輪郭を描く
// longitudinalbackpenは球の下半分のペンを指定するようだ
draw(s,m=1,longitudinalbackpen=currentpen+solid);

// x,y,z軸を描く
draw(O--2X,Arrow3);
draw(O--1.8Y,Arrow3);
draw(O--1.3Z,Arrow3);
label("$x$",1.6X,NW,currentpen+fontsize(30pt));
label("$y$",1.3Y,S,currentpen+fontsize(30pt));
label("$z$",1.1Z,NE,currentpen+fontsize(30pt));

real phi = pi/3, theta = pi/4;

triple H = (cos(phi),sin(phi),0);
triple P = expi(pi/2-theta,phi);//(cos(phi)*cos(theta),sin(phi)*cos(theta),sin(theta));
// 原点Oから点H,Pに直線を引く
draw(O--H);
draw(O--P);
label("$P$",P,NE,fontsize(20pt));
label("$H$",H,S,fontsize(20pt));
/*
dot(X);
dot(Y);
dot(Z);
dot(P);
*/

draw(arc(O,H,Z));

draw(arc(O,0.3X,0.3H));
draw(arc(O,0.3P,0.3H));
label("$\varphi$",0.3*(cos(phi/2),sin(phi/2),0),S,fontsize(20pt));
label("$\theta$",0.3*expi(pi/2-theta/2,phi),E,fontsize(20pt));

球を描くのに使っているrevolution(回転体)という型はsolidsモジュール(ソースコードのbase/solids.asy)で定義されている。次に呼び出しているdraw関数のオーバーロードもそこで定義されていて、コメントとシグニチャを示すと

// Draw on picture pic the skeleton of the surface of revolution r.
// Draw the front portion of each of the m transverse slices with pen p and
// the back portion with pen backpen. Rotational arcs are based on
// n-point approximations to the unit circle.
void draw(picture pic=currentpicture, revolution r, int m=0, int n=nslice,
	  pen frontpen=currentpen, pen backpen=frontpen,
	  pen longitudinalpen=frontpen, pen longitudinalbackpen=backpen,
	  light light=currentlight, string name="",
          render render=defaultrender, projection P=currentprojection)

となる。

expi関数はC++で実装されているようで、triple.htripleクラス内で

  // Returns a unit triple in the direction (theta,phi), in radians.
  friend triple expi(double theta, double phi)
  {
    double sintheta=sin(theta);
    return triple(sintheta*cos(phi),sintheta*sin(phi),cos(theta));
  }

と定義されている。

スポンサーサイト
プロフィール

minoki

Author:minoki
好きなプログラミング言語:
Haskell,Lua
GitHubアカウント
Twitter

最新記事
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。