抄lrj的板子抄错了gg,然后还要顺时针输出,没了
计算几何板子++
圆的切线
#includeusing namespace std;typedef double db;const db EPS = 1e-6;int sgn(db x) { return x < -EPS ? -1 : EPS < x;}struct Poi { db x, y; Poi() {} Poi(db x, db y):x(x), y(y) {} db cross(const Poi&rhs) { return x * rhs.y - y * rhs.x; } db dot(const Poi&rhs) { return x * rhs.x + y * rhs.y; } db len2() { return dot(*this); } Poi operator + (const Poi&rhs) { return Poi(x + rhs.x, y + rhs.y); } Poi operator - (const Poi&rhs) { return Poi(x - rhs.x, y - rhs.y); } Poi operator * (db p) { return Poi(x * p, y * p); } Poi operator / (db p) { return Poi(x / p, y / p); } bool operator == (const Poi&rhs) { return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0; } Poi norm() { return Poi(-y, x); } db ang() { db a = atan2(y, x); if (a < 0) a += M_PI * 2; return a; }};struct Cir:Poi { db r; Cir() {} Cir(db _x, db _y, db r):r(r) { x = _x, y = _y; } Poi getPoi(db ang) { return Poi(x + cos(ang) * r, y + sin(ang) * r); }};int getTangents(Cir A, Cir B, Poi*a, Poi*b) { int cnt = 0; if (A.r < B.r) { swap(A, B), swap(a, b); } db d2 = (A - B).len2(); db rdiff = A.r - B.r; db rsum = A.r + B.r; if (d2 < rdiff * rdiff) return 0; db base = (B - A).ang(); if (sgn(d2) == 0 && sgn(A.r - B.r) == 0) return -1; if (sgn(d2 - rdiff * rdiff) == 0) { a[cnt] = A.getPoi(base); b[cnt] = B.getPoi(base); ++cnt; return 1; } db ang = acos((A.r - B.r) / sqrt(d2)); a[cnt] = A.getPoi(base + ang); b[cnt] = B.getPoi(base + ang); ++cnt; a[cnt] = A.getPoi(base - ang); b[cnt] = B.getPoi(base - ang); ++cnt; if (sgn(d2 - rsum * rsum) == 0) { a[cnt] = A.getPoi(base); b[cnt] = B.getPoi(M_PI + base); ++cnt; } else if (sgn(d2 - rsum * rsum) > 0) { ang = acos((A.r + B.r) / sqrt(d2)); a[cnt] = A.getPoi(base + ang); b[cnt] = B.getPoi(M_PI + base + ang); ++cnt; a[cnt] = A.getPoi(base - ang); b[cnt] = B.getPoi(M_PI + base - ang); ++cnt; } return cnt;}bool inTriangle(Poi x, Poi a, Poi b, Poi c) { int s0, s1, s2; s0 = sgn((a - x).cross(b - x)); s1 = sgn((b - x).cross(c - x)); s2 = sgn((c - x).cross(a - x)); return s0 == s1 && s1 == s2;}int getLineInter(Poi a, Poi b, Poi c, Poi d, Poi&i) { b = b - a, d = d - c; Poi u = a - c; db e = b.cross(d); if (sgn(e) == 0) return 0; db t = d.cross(u) / e; i = a + b * t; return 1;}bool isInteger(db x) { return sgn(x - floor(x)) == 0 || sgn(x - ceil(x)) == 0;}Poi A, B;Cir cirA[3], cirB[3];db dA[3], dB[3];bool inA, inB;struct Tag { Poi a[4], b[4]; int cnt;} tagLine[3];db disToLine(Poi p, Poi a, Poi b) { Poi v1 = b - a, v2 = p - a; return fabs(v1.cross(v2)) / sqrt(v1.len2());}bool ok(Poi x, Poi y, Poi z) { if (sgn(disToLine(A, x, y) - fabs(dA[0])) != 0) return false; if (sgn(disToLine(A, y, z) - fabs(dA[1])) != 0) return false; if (sgn(disToLine(A, x, z) - fabs(dA[2])) != 0) return false; if (sgn(disToLine(B, x, y) - fabs(dB[0])) != 0) return false; if (sgn(disToLine(B, y, z) - fabs(dB[1])) != 0) return false; if (sgn(disToLine(B, x, z) - fabs(dB[2])) != 0) return false; if (sgn((y - x).cross(z - x)) > 0) return false; printf("%.10lf %.10lf\n", x.x, x.y); printf("%.10lf %.10lf\n", y.x, y.y); printf("%.10lf %.10lf\n", z.x, z.y); return true;}bool isSolved(int a, int b, int c) { Poi p, q, o; if (!getLineInter(tagLine[0].a[a], tagLine[0].b[a], tagLine[1].a[b], tagLine[1].b[b], p)) return false; if (!getLineInter(tagLine[1].a[b], tagLine[1].b[b], tagLine[2].a[c], tagLine[2].b[c], q)) return false; if (!getLineInter(tagLine[2].a[c], tagLine[2].b[c], tagLine[0].a[a], tagLine[0].b[a], o)) return false; if (inA != inTriangle(A, p, q, o) || inB != inTriangle(B, p, q, o)) return false; //printf("%.12lf %.12lf\n", o.x, o.y); //printf("%.12lf %.12lf\n", p.x, p.y); //printf("%.12lf %.12lf\n", q.x, q.y); //puts(""); if (ok(p, q, o)) return true; if (ok(p, o, q)) return true; if (ok(q, p, o)) return true; if (ok(q, o, p)) return true; if (ok(o, p, q)) return true; if (ok(o, q, p)) return true; //if (isInteger(p.x) && isInteger(p.y) //&& isInteger(q.x) && isInteger(q.y) //&& isInteger(o.x) && isInteger(o.y)) { // // // // return true; //} return false;}int main() {#ifdef lol freopen("b.in", "r", stdin); freopen("b.out", "w", stdout);#endif inA = inB = true; scanf("%lf%lf", &A.x, &A.y); for (int i = 0; i < 3; ++i) { scanf("%lf", &dA[i]); cirA[i] = Cir(A.x, A.y, fabs(dA[i])); } if (dA[0] < 0) inA = false; scanf("%lf%lf", &B.x, &B.y); for (int i = 0; i < 3; ++i) { scanf("%lf", &dB[i]); cirB[i] = Cir(B.x, B.y, fabs(dB[i])); } if (dB[0] < 0) inB = false; //printf("%d\n", ok(Poi(0, 0), Poi(0, 12), Poi(16, 0))); //return 0; for (int j = 0; j < 3; ++j) { tagLine[j].cnt = getTangents(cirA[j], cirB[j], tagLine[j].a, tagLine[j].b); for (int i = 0; i < tagLine[j].cnt; ++i) { if (tagLine[j].a[i] == tagLine[j].b[i]) { tagLine[j].b[i] = tagLine[j].a[i] + (tagLine[j].a[i] - A).norm(); } } } for (int a = 0; a < tagLine[0].cnt; ++a) { for (int b = 0; b < tagLine[1].cnt; ++b) { for (int c = 0; c < tagLine[2].cnt; ++c) { if (isSolved(a, b, c)) { // puts(""); // continue; return 0; } } } } return 0;}