兩個圓的公切線
圓上任意一點擁有唯一的圓心角
struct circle\) 的極角進行旋轉即可求出切點,進而得到切線
情況 5 的內切線類似情況2
情況 6 的外公切線與情況4完全一樣
情況 6 的內切線也是先求出圓心角 \(\alpha\) ,如何求?\(\cos \alpha = \frac\)
// a[i] 存放第 i 條公切線與 圓a 的交點
int gettangents(circle a, circle b, point*a, point *b){
int cnt = 0;
// 以a為半徑更大的那個圓進行計算
if(a.r < b.r) return gettangents(b, a, b, a);
db d2 = (a.p-b.p).len2(); // 圓心距平方
db rdiff = a.r - b.r;// 半徑差
db rsum = a.r + b.r;//半徑和
if(d2 < rdiff * rdiff) return 0; // 情況1,內含,沒有公切線
vector ab = b.p - a.p;// 向量ab,其模對應圓心距
db base = atan2(ab.y, ab.x);// 求出向量ab對應的極角
if(d2 == 0 && a.r == b.r) return -1;// 情況3,兩個圓重合,無限多切線
if(d2 == rdiff * rdiff){ // 情況2,內切,有一條公切線
a[cnt] = a.point(base);
b[cnt] = b.point(base);cnt++;
return 1;
// 求外公切線
db ang = acos((a.r - b.r) / sqrt(d2)); //求阿爾法
// 兩條外公切線
a[cnt] = a.point(base+ang); b[cnt] = b.point(base+ang); cnt++;
a[cnt] = a.point(base-ang); b[cnt] = b.point(base-ang); cnt++;
if(d2 == rsum * rsum){ // 情況5,外切,if裡面求出內公切線
a[cnt] = a.point(base); b[cnt] = b.point(pi+base); cnt++;
else if(d2 > rsum * rsum){//情況6,相離,再求出內公切線
db ang = acos((a.r + b.r) / sqrt(d2));
a[cnt] = a.point(base + ang); b[cnt] = b.point(pi+base+ang);cnt++;
a[cnt] = a.point(base - ang); b[cnt] = b.point(pi+base-ang);cnt++;
// 此時,d2 < rsum * rsum 代表情況 4 只有兩條外公切線
return cnt;
求兩個圓公切線的模板
a i 和 b i 存放第 i 條公切線與 圓a 和 園b 的交點 返回值為切線的條數 如果沒有切線返回值為 1 intgettangents circle a,circle b,point a,point b 求外公切線 db ang acos a.r b.r sqrt d2 求阿爾法 兩條外公切...
求兩圓的公切線計算
關於兩圓的公切線計算我們首先需要搞清楚的是兩個圓之間有哪些位置關係,兩個圓的位置包括內含 內切 外切 外離幾種方式,可以看出位置關係可以根據 兩圓心之間的距離 與 兩圓半徑和 以及 兩圓半徑差 之間的關係判斷。假設大圓半徑為r,小圓半徑為 r,把 兩圓心之間的距離 表示為d,兩圓半徑和 表示為s,兩...
圓的公切線演算法實現
返回外切線方程 求切線的k k 2 deltar 2 deltax 2 2k deltax deltay deltar 2 deltay 2 0 public static linesegment getexternaltangent round r1,round r2 else double b1...