[Illustratorスクリプト] 円をくっつけて並べる
わたしも流行りに乗っかってChatGTPなんか使ってみたりします。Illustratorのジオメトリックな処理をお願いしたりするのですが、今まで意図した通りのものを書いてくれたことはありません。三角関数とか利用するのがとっても下手くそで、正しい回答にたどり着けずループするという事を何度も経験しています。返ってくるのはもっともらしく書かれた大嘘だったりするので、ここらへんの事に関しては自分で考えるのが手っ取り早いということかと思います。
という事で今回は3つの円を接するように描いてみます。
3つの円をくっつけるには各円の中心を結ぶ三角形の情報があればOKです。各辺はそれぞれの円の半径から決まりますので、この三角形の各辺の長さが決まっていることになります。
ここで、各頂点の位置関係はどうなるかと言うと2つの円の中心を結ぶ線分の両端の位置がわかりますので2点までは単純に得られます。3つ目の頂点は先の2つの頂点からの距離はわかっていますが、2つの頂点を結ぶ線分との角度を計算する必要があります。この部分をChatGTPさんに聞いても三角関数を使ってくれなかったりするのでとってもアレでした。 まあ、色々と手法はあるのですけど、今回は余弦定理(https://ja.wikipedia.org/wiki/余弦定理)の応用で行きます。
var r = eval(prompt("Input Radius","[120,70,30]")); var pt0 = [100,-200]; //base point r.sort(sortNum) var b = r[0]+r[2]; var c = r[1]+r[2]; var a = r[0]+r[1]; var pt1 = [pt0[0]+a, pt0[1]]; var pt2 = get3rdPoint(pt0, pt1, b, c) if (pt2) { var pth = app.activeDocument.pathItems; pth.ellipse(pt0[1]+r[0], pt0[0]-r[0], r[0]*2, r[0]*2) pth.ellipse(pt1[1]+r[1], pt1[0]-r[1], r[1]*2, r[1]*2) pth.ellipse(pt2[1]+r[2], pt2[0]-r[2], r[2]*2, r[2]*2) } function get3rdPoint(pt0, pt1, b, c) { var a = Math.sqrt((pt1[0]-pt0[0])*(pt1[0]-pt0[0])+(pt1[1]-pt0[1])*(pt1[1]-pt0[1]) ); var angle = Math.acos((b*b+a*a-c*c)/(2*b*a)); if (isNaN(angle)) return false; var x = pt0[0] + Math.cos(angle)*b; var y = pt0[1] + Math.sin(angle)*b; return [x,y]; } function sortNum(a,b) { if (a>b) return -1; else if (a<b)return 1; else return 0; }
このコードで肝心なところはget3rdPoint関数の2行目です。余弦定理で得られた値は余弦ですからMathクラスのacosを利用して逆余弦を取って角度を得ます。
この角度と各半径から得られた辺の長さを基に3つ目の頂点の位置を決定します。あとは各頂点を中心として円を描けばOKです。