兩個圓的公切線


兩個圓的公切線

圓上任意一點擁有唯一的圓心角

struct circle{
    Point p;
    double r;
    // 通過圓心角求圓上某一點
    Point point(double a){
        return Point(p.x + cos(a) * r, c.y + sin(a) * r);
    }
}

根據兩個圓的位置關系來確定情況

  1. 兩個圓內含,沒有公共點,沒有公切線
  2. 兩圓內切,有一個條公切線
  3. 兩圓完全重合,有無數條公切線
  4. 兩圓相交。有2條公切線
  5. 兩圓外切,有3條公切線
  6. 兩圓相離,有4條公切線

1 與 3 什么都不求,情況 2 可以直接求出直線AB的極角進而轉換為圓心角來求切點,連接切點和圓心,旋轉90度即可得到切線。

情況 4 有兩條外公切線,求出圓心距 \(d\) 以及\(|AG|\) 即可求出 \(\alpha\) 的大小,根據 \(\vec{AB}\) 的極角進行旋轉即可求出切點,進而得到切線

情況 5 的內切線類似情況2

情況 6 的外公切線與情況4完全一樣

情況 6 的內切線也是先求出圓心角 \(\alpha\) ,如何求?\(\cos \alpha = \frac{A_r+B_r}{|AB|}\)

// 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;
}

例題測試:https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_G


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM