2つの円に共通する接線を求めてみようと思います。接線は、それぞれの円の接点を求めることと同じになりますが、この接点は、Math.acos でわりと単純に求めることができます。
上の図のように、2つの円の中心を結ぶベクトルをvとします。接線ができるのは、2つの円について、vからの角度が同じθの場合と、θとθ+Math.PI の場合です。どちらも、vの角度から±θのところが接点になります。また、θとθ+Math.PIの場合は、2つの接線が交差します。
cosθは、上図のような関係になるので、θは、
a1 = Math.acos( (r0-r1)/v.length ); a2 = Math.acos( (r0+r1)/v.length );
で求めることができます。θは、(r0-r1)、(r0+r1)が、v.lengthより大きい場合は成立しませんから、その場合、接線はないことになります。
接点の座標は、vの角度から±θになるので、
/** * 円0: 中心( x0, y0 ) 半径 r0 * 円1: 中心( x1, y1 ) 半径 r1 * */ dr:Number = r0-r1; if( Math.abs(dr)<=v.length ){ //接線あり //vの角度 var a0:Number = Math.atan2( v.y, v.x ); //接点の角度1 var a1:Number = Math.acos( dr/v.length ); //円0の接点 var tp01:Point = new Point( x0 + r0*Math.cos(a0+a1), y0 + r0*Math.sin(a0+a1) ); var tp02:Point = new Point( x0 + r0*Math.cos(a0-a1), y0 + r0*Math.sin(a0-a1) ); //円1の接点 var tp11:Point = new Point( x1 + r1*Math.cos(a0+a1), y1 + r1*Math.sin(a0+a1) ); var tp12:Point = new Point( x1 + r1*Math.cos(a0-a1), y1 + r1*Math.sin(a0-a1) ); dr = r0+r1; if( dr<v.length ){ //接点の角度2 var a2:Number = Math.acos( dr/v.length ); //円0の接点 var tp03:Point = new Point( x0 + r0*Math.cos(a0+a2), y0 + r0*Math.sin(a0+a2) ); var tp04:Point = new Point( x0 + r0*Math.cos(a0-a2), y0 + r0*Math.sin(a0-a2) ); //円1の接点 var tp13:Point = new Point( x1 + r1*Math.cos(a0+a2+Math.PI), y1 + r1*Math.sin(a0+a2+Math.PI) ); var tp14:Point = new Point( x1 + r1*Math.cos(a0-a2+Math.PI), y1 + r1*Math.sin(a0-a2+Math.PI) ); }else if( dr==v.length ){ //円が接している 接点 var tp05:Point = new Point( x0 + r0*Math.cos(a0), y0 + r0*Math.sin(a0) ); } }
//追記:2010/10/17修正しました
のようになります。
接線だけなら、a0、a1、a2を求めて、円1についての接線を求めればよいことになります。