• UVA-12304


    一年前写的代码,保存一下计算几何板子。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    template<typename Tp>
    void Push(vector<Tp> &a, vector<Tp> b) {
        for (int i = 0; i < b.size(); ++i)
    	a.push_back(b[i]);
        return;
    }
    const double EPS = 1E-12, Pi = acos(-1);
    
    inline int Sgn(double x) {
        return (x < -EPS) ? (-1) : (x > EPS);
    }
    int Cmp(double a, double b) {
        return Sgn(a - b);
    }
    
    struct Point {
        double x, y;
        Point(double x = 0, double y = 0) : x(x), y(y) {}
        bool operator < (const Point &a) const {
    	return (Sgn(x - a.x)) ? (x < a.x) : (y < a.y);
        }
        bool operator == (const Point &a) const {
    	return !Sgn(x - a.x) && !Sgn(y - a.y);
        }
    };
    
    typedef Point Vector;
    
    Point Read_Point() {
        Point a;
        scanf("%lf%lf", &a.x, &a.y);
        return a;
    }
    double Polar_Angle(Point a) {
        return atan2(a.y, a.x);
    }
    double Distance(Point a, Point b) {
        return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
    }
    Vector operator + (Vector a, Vector b) {
        return Vector(a.x + b.x, a.y + b.y);
    }
    Vector operator - (Point a, Point b) {
        return Vector(a.x - b.x, a.y - b.y);
    }
    Vector operator - (Point a) {
        return Vector(-a.x, -a.y);
    }
    Vector operator * (Vector a, double k) {
        return Vector(a.x * k, a.y * k);
    }
    Vector operator * (double k, Vector a) {
        return Vector(a.x * k, a.y * k);
    }
    Vector operator / (Vector a, double k) {
        return Vector(a.x / k, a.y / k);
    }
    Vector operator / (double k, Vector a) {
        return Vector(a.x / k, a.y / k);
    }
    double Dot(Vector a, Vector b) {
        return a.x * b.x + a.y * b.y;
    }
    double Length(Vector a) {
        return sqrt(Dot(a, a));
    }
    double Cross(Vector a, Vector b) {
        return a.x * b.y - b.x * a.y;
    }
    Vector Reflect(Vector a) {
        return Vector(a.x, -a.y);
    }
    Vector Unit(Vector a) {
        return a / Length(a);
    }
    Vector Rotate(Vector a, Vector b) {
        b = Unit(b);
        return Vector(a.x * b.x - a.y * b.y, a.x * b.y + b.x * a.y);
    }
    Vector Normal(Vector a) {
        return Vector(-a.y, a.x) / Length(a);
    }
    
    struct Angle {
        Vector u, v1, v2;
        Angle(Vector u, Vector v1, Vector v2) : u(u), v1(Unit(v1)), v2(Unit(v2)) {}
    };
    
    double Cosine(Angle a) {
        return Dot(a.v1, a.v2); 
    }
    
    struct Line {
        Vector u, v;
        Line(Vector u, Vector v) : u(u), v(Unit(v)) {}
    };
    
    Line Read_Line() {
        Point a = Read_Point(), b = Read_Point();
        return Line(a, b - a);
    }
    Line Rotate(Line a, Vector b) {
        return Line(a.u, Rotate(a.v, b));
    }
    double Polar_Angle(Line a) {
        if (a.v.y <= 0) a.v = -a.v;
        return Polar_Angle(a.v);
    }
    Point Get_Line_Intersection(Line a, Line b) {
        return a.u + a.v * (Cross(b.v, a.u - b.u) / Cross(a.v, b.v));
    }
    double Distance_To_Line(Point a, Line b) {
        return fabs(Cross(b.v, a - b.u));
    }
    Point Get_Line_Projection(Point a, Line b) {
        return b.u + b.v * Dot(b.v, a - b.u);
    }
    
    struct Segment {
        Point u, v;
        Segment(Point u, Point v) : u(u), v(v) {}
    };
    
    Segment Read_Segment() {
        Point a = Read_Point(), b = Read_Point();
        return Segment(a, b);
    }
    double Length(Segment a) {
        return Length(a.v - a.u);
    }
    Point Midpoint(Segment a) {
        return (a.u + a.v) / 2;
    }
    
    // double Distance_To_Segment(Point b, Segment b) {}
    // bool Segment_Proper_Intersection(Segment a, Segment b) {}
    // bool On_Segment(Point a, Segment b) {}
    
    Line Angle_Bisector(Angle a) {
        return Line(a.u, a.v1 + a.v2);
    }
    Line Perpendicular_Bisector(Segment a) {
        return Line(Midpoint(a), Normal(a.v - a.u));
    }
    
    struct Circle {
        Point c;
        double r;
        Circle(Point c, double r = 0) : c(c), r(r) {}
    };
    
    Circle Read_Circle() {
        Point a = Read_Point();
        double r;
        scanf("%lf", &r);
        return Circle(a, r);
    }
    Circle Circumscribed_Circle(Point a, Point b, Point c) {
        Point cc = Get_Line_Intersection(Perpendicular_Bisector(Segment(a, b)), Perpendicular_Bisector(Segment(b, c)));
        return Circle(cc, Distance(cc, a));
    }
    Circle Inscribed_Circle(Point a, Point b, Point c) {
        Point cc = Get_Line_Intersection(Angle_Bisector(Angle(a, b - a, c - a)), Angle_Bisector(Angle(b, a - b, c - b)));
        return Circle(cc, Distance_To_Line(cc, Line(a, b - a)));
    }
    vector<Point> Get_Line_Circle_Intersection(Line a, Circle b) {
        vector<Point> res;
        double h = Distance_To_Line(b.c, a);
        if (Cmp(b.r, h) < 0) return res;
        Point c = Get_Line_Projection(b.c, a);
        if (!Cmp(h, b.r)) {
    	res.push_back(c);
    	return res;
        }
        double w = sqrt(b.r * b.r - h * h);
        res.push_back(c + a.v * w);
        res.push_back(c - a.v * w);
        sort(res.begin(), res.end());
        return res;
    }
    vector<Point> Get_Circle_Intersection(Circle a, Circle b) {
        vector<Point> res;
        if (a.r < b.r) swap(a, b);
        double h = Distance(a.c, b.c);
        if (Cmp(h, a.r + b.r) > 0) return res;
        if (Cmp(h, a.r - b.r) < 0) return res;
        if (!Cmp(h, a.r + b.r) || !Cmp(h, a.r - b.r)) {
    	Line x(a.c, b.c - a.c);
    	res.push_back(x.u + x.v * a.r);
    	return res;
        }
        double cosine = (h * h + a.r * a.r - b.r * b.r) / (2 * h * a.r);
        Vector alpha(cosine, sqrt(1 - cosine * cosine)), k = Unit(b.c - a.c);
        res.push_back(a.c + Rotate(k, alpha) * a.r);
        res.push_back(a.c + Rotate(k, Reflect(alpha)) * a.r);
        sort(res.begin(), res.end());
        return res;
    }
    
    vector<double> Tangent_Line_Through_Point(Point a, Circle b) {
        vector<double> res;
        double h = Distance(a, b.c);
        if (Cmp(h, b.r) < 0) return res;
        if (!Cmp(h, b.r)) {
    	res.push_back(Polar_Angle(Normal(a - b.c)));
    	return res;
        }
        double w = sqrt(h * h - b.r * b.r);
        Vector alpha(w, b.r);
        Line x(a, b.c - a);
        res.push_back(Polar_Angle(Rotate(x, alpha)) * 180 / Pi);
        res.push_back(Polar_Angle(Rotate(x, Reflect(alpha))) * 180 / Pi);
        sort(res.begin(), res.end());
        return res;
    }
    vector<Point> Circle_Through_A_Point_And_Tangent_To_A_Line_With_Radius(Point a, Line b, double r) {
        vector<Point> res;
        Vector c = Normal(b.v);
        Circle k(a, r);
        Push(res, Get_Line_Circle_Intersection(Line(b.u + c * r, b.v), k));
        Push(res, Get_Line_Circle_Intersection(Line(b.u - c * r, b.v), k));
        sort(res.begin(), res.end());
        return res;
    }
    vector<Point> Circle_Tangent_To_Two_Lines_With_Radius(Line a, Line b, double r) {
        vector<Point> res;
        Point c = Get_Line_Intersection(a, b);
        Angle alpha(c, a.v, b.v);
        Line x = Angle_Bisector(alpha);
        double cosine = Cosine(Angle(c, x.v, b.v));
        Point cc = x.u + x.v * (r / sqrt(1 - cosine * cosine));
        res.push_back(cc);
        res.push_back(c * 2 - cc);
        alpha = Angle(c, a.v, -b.v);
        x = Angle_Bisector(alpha);
        cosine = Cosine(Angle(c, x.v, b.v));
        cc = x.u + x.v * (r / sqrt(1 - cosine * cosine));
        res.push_back(cc);
        res.push_back(c * 2 - cc);
        sort(res.begin(), res.end());
        return res;
    }
    vector<Point> Circle_Tangent_To_Two_Disjoint_Circles_With_Radius(Circle a, Circle b, double r) {
        return Get_Circle_Intersection(Circle(a.c, a.r + r), Circle(b.c, b.r + r));
    }
    
    char buff[100];
    
    void Write(Point a) {
        printf("(%.6f,%.6f)", a.x, a.y);
        return;
    }
    void Write(Circle a) {
        printf("(%.6f,%.6f,%.6f)", a.c.x, a.c.y, a.r);
        return;
    }
    void Write(vector<double> a) {
        putchar('[');
        if (a.size()) printf("%.6f", a[0]); 
        for (int i = 1; i < a.size(); ++i)
    	printf(",%.6f", a[i]);
        putchar(']');
        return;
    }
    void Write(vector<Point> a) {
        putchar('[');
        if (a.size()) Write(a[0]);
        for (int i = 1; i < a.size(); ++i) {
    	putchar(',');
    	Write(a[i]);
        }
        putchar(']');
        return;
    }
    
    int main() {
        while (scanf("%s", buff + 1) == 1) {
    	int len = strlen(buff + 1);
    	if (len == 19) {
    	    Point a = Read_Point(), b = Read_Point(), c = Read_Point();
    	    Write(Circumscribed_Circle(a, b, c));
    	} else if (len == 15) {
    	    Point a = Read_Point(), b = Read_Point(), c = Read_Point();
    	    Write(Inscribed_Circle(a, b, c));
    	} else if (len == 23) {
    	    Circle a = Read_Circle();
    	    Point b = Read_Point();
    	    Write(Tangent_Line_Through_Point(b, a));
    	} else if (len == 46) {
    	    Point a = Read_Point();
    	    Line b = Read_Line();
    	    double r;
    	    scanf("%lf", &r);
    	    Write(Circle_Through_A_Point_And_Tangent_To_A_Line_With_Radius(a, b, r));
    	} else if (len == 33) {
    	    Line a = Read_Line(), b = Read_Line();
    	    double r;
    	    scanf("%lf", &r);
    	    Write(Circle_Tangent_To_Two_Lines_With_Radius(a, b, r));
    	} else {
    	    Circle a = Read_Circle(), b = Read_Circle();
    	    double r;
    	    scanf("%lf", &r);
    	    Write(Circle_Tangent_To_Two_Disjoint_Circles_With_Radius(a, b, r));
    	}
    	putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    rpc中的stub学习
    Centos7 远程打开火狐浏览器 控制台输入命令:firefox profilemanager
    centos7 networkmanager 与 interfaces 冲突 ,实际未成功,
    centos7如何更改系统语言为英文
    虚拟机centos7安装VMwareTools详细教程 注意命令中 #要去掉
    linux centos7系统怎么查看设置ip
    CentOS 7 虚拟机安装&网络配置&链接xshell&换源,亲测可行运行
    centos7系统的ping命令出现 www.baidu.com Name or service not known
    Centos 7下如何调用中文输入法
    centos7查看ip命令,centos7设置虚拟机ip 修改 vi/etc/sysconfig/networkscripts/ifcfgens33 配置为 yes 可显示ip地址
  • 原文地址:https://www.cnblogs.com/tkandi/p/10506236.html
Copyright © 2020-2023  润新知