zoukankan      html  css  js  c++  java
  • XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan B. White Triangle

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

    计算几何板子++

    圆的切线

    #include <bits/stdc++.h>
    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
    ", x.x, x.y);
        printf("%.10lf %.10lf
    ", y.x, y.y);
        printf("%.10lf %.10lf
    ", 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
    ", o.x, o.y);
        //printf("%.12lf %.12lf
    ", p.x, p.y);
        //printf("%.12lf %.12lf
    ", 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
    ", 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;
    }
  • 相关阅读:
    python 扁平列表转树状字典
    在Windows Server2012中通过DockerToolbox 一步一步搭建Mysql 数据库存运行环境
    腾讯云ubuntu服务器安装图像化界面并实现远程登陆
    IIS、apache、tomcat服务器虚拟主机配置
    微信商家二维码到底是什么
    线程与线程锁---python版本(附带线程锁实例)
    pip更新后仍旧是使用的旧版本
    pip更新后仍旧是使用的旧版本
    H5-LocalStorage
    Python摄像头抓拍的彩色图像转为灰度图、二值化和调整图片尺寸(实例)
  • 原文地址:https://www.cnblogs.com/ichn/p/7639761.html
Copyright © 2011-2022 走看看