求两个圆公切线的模板

    科技2024-10-10  126

    // a[i] 和 b[i]存放第 i 条公切线与 圆A 和 园B 的交点 // 返回值为切线的条数 如果没有切线返回值为-1 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; }
    Processed: 0.013, SQL: 8