読者です 読者をやめる 読者になる 読者になる

2円をつなぐ線を描く

図形を描く系のコードでやっている計算を図解するシリーズ。
を、ときどき書いていこうと思います。

(Illustrator用のJavaScript script編)

math なんていうタグまでつけていますが。

数学とは私にとって高校のころに唯一、赤点を取った科目です。
逆にだからこそこういう、中学か高校の図形の練習問題みたいなものでも、 ちょっとしたパズルを解くような感じでいまだに楽しめているのではないかと思います。

という言い訳をしたためたうえで、

本題

f:id:shspage:20170326142425p:plain

こんなふうに2円 をつなぐ線をたくさん描いたら面白い形になるかなと思って、 書いてみた処理の話。 *1

とりあえず、分かっている部分を描いて計算方法を考えます。
Illustratorなので、円の中心と半径はそれぞれのパスの属性からわかります。 *2

(2017.03.31 脚注2の中心と半径の求め方を修正しました。)

f:id:shspage:20170327233503p:plain:w250

こうやって図で描くと図形問題そのものですね。
大人になってからこんなものが役に立つとは思ってもいませんでしたし、
こんなものに悩まされるとも思っていませんでした。

それはさておき、接線を引くには接点 P1, P2 の位置が知りたい。

円の中心(O1)と接点(P1)を結んだ線の角度は、
「2円の中心を結んだ線の角度 + t 」です。
角度 t を知りたい。

f:id:shspage:20170327233522p:plain:w250

円の接線は接点と中心を結んだ線と直角に交わるので、
中心と接点を結んだ2本の線 (R1, R2) は、錯角が等しいため平行ということも分かります。

R2 を R1 の隣にコピーしてやると、O1-O2'-O2 という直角三角形ができます。

つまり cos(t) = (R1 + R2) / d

角度 t = arccos((R1 + R2) / d)

ここまでわかったところで、とりあえずIllustratorで動くコードにまとめてみます。

gist.github.com

ちなみに円の外側で接線を引く場合は下の図のようになります。

考え方は同じようなもので、
角度 t の値は Math.acos((R1 - R2) / d) で求められます。

f:id:shspage:20170327233613p:plain:w250

で、

さらにたくさんつなげるようにしてみた結果。

f:id:shspage:20170328065708p:plain

あんまり面白くない。
もう少し工夫が必要。

*1:Illustratorの楕円ツールで描いた円は誤差があって厳密には正円ではないですが、 今回の用途では問題になる誤差ではないので円として扱います。

*2:後述の例の geometricBounds を使う方法のほかにこれでもよいです。 var w = 0; if(path.stroked) w = path.strokeWidth / 2; (中心=) ver x = path.left + w + path.width / 2; var y = path.top - w - path.height / 2; (半径=) var radius = path.width / 2;