博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan B. White Triangle
阅读量:5271 次
发布时间:2019-06-14

本文共 5947 字,大约阅读时间需要 19 分钟。

抄lrj的板子抄错了gg,然后还要顺时针输出,没了

计算几何板子++

圆的切线

#include 
using 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;}

 

转载于:https://www.cnblogs.com/ichn/p/7639761.html

你可能感兴趣的文章
排序sort (一)
查看>>
Parrot虚拟机
查看>>
Teamcenter10 step-by-step installation in Linux env-Oracle Server Patch
查看>>
Redis-jedis模拟多线程购票
查看>>
Gcc 安装过程中部分配置
查看>>
他看了几千份技术简历,愿意把技术简历的秘籍传授给你
查看>>
Struts2学习(三)
查看>>
使用电子邮件模板
查看>>
Callable和Runnable和FutureTask
查看>>
GitHub 多人协作开发 三种方式:
查看>>
文本域添加编辑器
查看>>
Yum安装MySQL以及相关目录路径和修改目录
查看>>
java获取hostIp和hostName
查看>>
RxJava结合Retrofit和Volley简单比较
查看>>
iOS 企业版 安装失败 原因
查看>>
ThreadLocal 理解
查看>>
关于web服务器和数据库的各种说法(搜集到的)
查看>>
一个 forceLayout() 和 requestLayout() 的测试
查看>>
【转】使用js触发事件
查看>>
《TCP/IP 详解 卷一》读书笔记 -----第四章 ARP
查看>>