3つの円の隙間に円を描く

図形を描く系のコードでやっている計算を図解するシリーズ。

(Illustrator用のJavaScript script編)

これは基礎知識級のことなのかもしれないのですが、
私は初めて知って面白いと思ったので、

本題

1. 同じ大きさの3円の場合

f:id:shspage:20170331233303p:plain

同じ大きさの円を3つ適当に描いたとき、3つの円に接する円が描けます。
(3円が直線上に並んでいるときを除く。)

こんなふうに。

f:id:shspage:20170331233321p:plain

しくみ

3つのうち2つの円に接する円の中心は、 2円の中心から等距離の点の軌跡、 つまり2円の中心を結んだ線の垂直二等分線上にあります。

f:id:shspage:20170331233432p:plain

中心を結んで三角形をつくると、 各辺の垂直二等分線の交点は三角形の外心(外接円の中心)なので、 3円に接する円の中心が1点に決まるのは当然といえば当然なわけです。

f:id:shspage:20170331233502p:plain

仕組みが分かると詰まらない気もしますが、 ブログの性格上、スクリプトにしたものを掲載します。

gist.github.com

円が重なってる場合はこんなふうになっちゃいますねこれ。

外側で接するとは言ってないからこれもアリか。

f:id:shspage:20170331234442p:plain

2. 違う大きさの3円の場合

雰囲気的には描けそうなんですが、これが思ったより難しく、

調べたらこれは「アポロニウスの問題」というものだそうで、 ネット上で色々な解法が見つけられますがどれもややこしいです。

手に負えそうな解法のひとつを参考にさせていただき、 スクリプトにしてみましたが、このシリーズに載せるには複雑になってしまいました。 内容はまた何かの機会に図解したいと思います。

Illustratorで3円に接する円を描く · GitHub

1つだけ補足すると、3円に接する円の半径を大きく(or小さく)した場合、 3円のほうの半径を同じ分だけ小さく(or大きく)すると接した状態が保たれる のだそうで(アポロニウスの問題 - Wikipedia )、スクリプトに使った解法でもこの事実を利用しています。

上の「1.」でやっていることも、三角形の外接円に接する頂点を半径0の円と 考えると、3つの円に接するケースはそれらの半径を増やしただけのことともいえます。


おわび】前回、脚注2で円の中心と半径を簡単に求める方法として 載せたものが間違っていたため修正しました。

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;

Adobe Illustrator SDK メモ (1)

Visual Studio 2015 Community で Adobe Illustrator CC 2017 SDK を使ってのプラグイン作成、についてのメモです。

サンプルコードのビルド

全部はビルドしてみていないですが、
afxres.h がないというエラーが出た場合は resource.rc の afxres.h を winres.h に変更すると通ります。

Template の導入

テンプレートを適切な場所に置いてやると、新規プロジェクト作成の一覧の中に IllustratorSDK というのが出てきます。

Windows用テンプレートの関連ファイルは以下のフォルダにあります。

samplecode\Templates\Win

INSTALL.txt に従ってファイルを配置する前に、

Illustrator.vsz をエディタで開いて1行目と2行目を以下のように書き換え。

VSWIZARD 7.0
Wizard=VsWizard.VsWizardEngine.14.0

前述の afxres.h がないなら resource.rc も修正。

あとはINSTALL.txt に従います。

ただし INSTALL.txt の1行目Visual Studio 11.0はVisual Studio 14.0 に読み替え。
“5.” の copy the folder IllustratorSDK.vsdir は copy the file IllustratorSDK.vsdir の間違いでしょう。

“12.” にあるように、プロジェクト作成時には Create Directory For Solution をチェックしないように注意です。

つづく

現時点で近々具体的に何か作る予定はないです。あればまた。