久しぶりに Asymptote によるお絵描きの練習。
ホントはフォード・サークルを描きたかったのだが、まだ繰り返し処理などのプログラムを書けないので、2円と直線に外接する第3の円を描くことで満足することにした。円の中心は半径は事前に計算式を作って求めるようにする必要がある。しかし、計算自体はプログラムがやってくれるので、半径を変えたいときは、a, bを変えるだけで、あとのコードはそのままで構わない。
破線は dashed というペンを選べばよいのだが、標準のものは少し間延びしているように感じたので、少しだけ変更した。
geometryというモジュールをimportすれば、円と直線の交点、2円の交点をプログラムに求めさせることが出来る。これは、intersectionpoints という関数で成される。交点は2個あるため、結果は配列になる。
/*
Asymptoteの練習 No.0003
直線lに接し、互いに接する2円C1,C2に対して、この3つに接する円を描く。
t0003.asy
*/
// usepackage("amsmath");
usepackage("MinionPro"); // 数式フォントをMinionProに設定
import fontsize; // font サイズ変更のため
import geometry; // 初等幾何用のモジュール
defaultpen(fontsize(11)); // フォントサイズを11ポイントに設定
defaultpen(linewidth(0.4pt)); // 線の太さを0.4ポイントに設定
dotfactor=6; // 黒丸のサイズは線の太さの6倍に設定
// pen dashed=linetype("6 6");
// pen dashed=linetype("3 3");
pen dashed=linetype("4 4"); // 破線の長さを少し変更する。
pen thick=linewidth(0.6pt); // 太線用のペンを定義する。
size(6cm,0); // 出来上がりの図版のサイズを幅6センチに設定
// unitsize(5mm);
/*
最初に互いに外接する2円c1,c2の半径a,bを定める。3番目の円c3の半径cは
1/sqrt(c)=1/sqrt(a)+1/sqrt(b)
により計算される。
3円の共通接線l上での接点P,Q,Rの座標をx1(=0), x2,x3とする。
これらは、共通接線の長さ
PQ=2sqrt(ab), PR=2sqrt(ac)
により計算される。
*/
real a=3.7, b=5; // 互いに外接する2円の半径
real c=(a*b)/(sqrt(a)+sqrt(b))^2;
real x1, x2, x3; // 共通接線上での接点の位置
x1=0;
x2=2*sqrt(a*b);
x3=2*sqrt(a*c);
/*
3円の中心A,B,Cの座標を設定する。
点Aに対するpair(=point)としては、pAという記号を用いることにする。(pはpointの意味)
次に、A,B,Cを中心とする半径a,b,cの円c1,c2,c3を作る。
*/
point pA=(x1,a), pB=(x2,b), pC=(x3,c);
circle c1=circle(pA,a), c2=circle(pB,b), c3=circle(pC,c);
/*
接点P,Q,Rの座標と、共通接線の両端M,Nを設定する。
*/
point pP=(x1,0), pQ=(x2,0), pR=(x3,0), pM=(x1-a,0), pN=(x2+b,0);
/*
2円の接点をいろんな形で求めてみる。
segmentは線分を意味する。以下では、seg1は線分ABとなる。
直線と円の交点は一般には2個になるので、intersectionpoints (複数形に注意) の
値は配列になっている。最初に交点にアクセスするために [0] としている。
*/
segment seg1=segment(pA,pB);
point pT1=intersectionpoints(seg1,c1)[0];
point pT2=intersectionpoints(pA--pC,c1)[0];
point pT3=intersectionpoints(c2,c3)[0];
/*
太めのペンで3つの円と共通接線を描く。
*/
draw(c1,thick);
draw(c2,thick);
draw(c3,thick);
draw(pM--pN,thick);
/*
標準のペンで、中心を結ぶ線分などを波線で描く。
*/
draw(seg1,dashed);
draw(pA--pC,dashed);
draw(pB--pC,dashed);
draw(pA--pP,dashed);
draw(pB--pQ,dashed);
draw(pC--pR,dashed);
/*
接点に直角マークを付ける。サイズは1.5mmと直接指定した。
標準だと大きすぎた。標準を変更する方法があると良いのだが。
*/
markrightangle(pA,pP,pM,1.5mm);
markrightangle(pB,pQ,pM,1.5mm);
markrightangle(pC,pR,pM,1.5mm);
/*
接点に位置にドット(黒丸)とラベルを描く。
ドットのサイズは、linewidth*dotfactorになる。
また、
dot("P",pP,S,red+linewidth(0.8mm));
のように、直接 linewidthや色を指定することも可能。
ドットを白抜きにする方法を知りたい。
ラベルに位置は、東西南北(EWSN)などで指定できる。
東北(EN)や東北東(ENE)なども可能。
*/
dot("P",pP,S);
dot("Q",pQ,S);
dot("R",pR,S);
dot("$\mathrm{O}_1$",pA,N);
dot("$\mathrm{O}_2$",pB,N);
dot(pC);
dot(pT1);
dot(pT2);
dot(pT3);
label("$l$",pM,W);
addMargins(2mm,2mm);