uva 12304点与直线与圆之间的关系

Problem E

2D Geometry 110 in 1!

This is a collection of 110 (in binary) 2D geometry problems.

CircumscribedCircle x1 y1 x2 y2 x3 y3

Find out the circumscribed circle of triangle (x1,y1)-(x2,y2)-(x3,y3). These three points are guaranteed to be non-collinear. The circle is formatted as (x,y,r) where (x,y) is the center of circle, r is the radius.

InscribedCircle x1 y1 x2 y2 x3 y3

Find out the inscribed circle of triangle (x1,y1)-(x2,y2)-(x3,y3). These three points are guaranteed to be non-collinear. The circle is formatted as (x,y,r) where (x,y) is the center of circle, r is the radius.

TangentLineThroughPoint xc yc r xp yp

Find out the list of tangent lines of circle centered (xc,yc) with radius r that pass through point (xp,yp). Each tangent line is formatted as a single real number "angle" (in degrees), the angle of the line (0<=angle<180). Note that the answer should be formatted as a list (see below for details).

CircleThroughAPointAndTangentToALineWithRadius xp yp x1 y1 x2 y2 r

Find out the list of circles passing through point (xp, yp) that is tangent to a line (x1,y1)-(x2,y2) with radius r. Each circle is formatted as (x,y), since the radius is already given. Note that the answer should be formatted as a list. If there is no answer, you should print an empty list.

CircleTangentToTwoLinesWithRadius x1 y1 x2 y2 x3 y3 x4 y4 r

Find out the list of circles tangent to two non-parallel lines (x1,y1)-(x2,y2) and (x3,y3)-(x4,y4), having radius r. Each circle is formatted as (x,y), since the radius is already given. Note that the answer should be formatted as a list. If there is no answer, you should print an empty list.

CircleTangentToTwoDisjointCirclesWithRadius x1 y1 r1 x2 y2 r2 r

Find out the list of circles externally tangent to two disjoint circles (x1,y1,r1) and (x2,y2,r2), having radius r. By "externally" we mean it should not enclose the two given circles. Each circle is formatted as (x,y), since the radius is already given. Note that the answer should be formatted as a list. If there is no answer, you should print an empty list.

For each line described above, the two endpoints will not be equal. When formatting a list of real numbers, the numbers should be sorted in increasing order; when formatting a list of (x,y) pairs, the pairs should be sorted in increasing order of x. In case of tie, smaller y comes first.

Input

There will be at most 1000 sub-problems, one in each line, formatted as above. The coordinates will be integers with absolute value not greater than 1000. The input is terminated by end of file (EOF).

Output

For each input line, print out your answer formatted as stated in the problem description. Each number in the output should be rounded to six digits after the decimal point. Note that the list should be enclosed by square brackets, and tuples should be enclosed by brackets. There should be no space characters in each line of your output.

Sample Input

CircumscribedCircle 0 0 20 1 8 17
InscribedCircle 0 0 20 1 8 17
TangentLineThroughPoint 200 200 100 40 150
TangentLineThroughPoint 200 200 100 200 100
TangentLineThroughPoint 200 200 100 270 210
CircleThroughAPointAndTangentToALineWithRadius 100 200 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 75 190 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 99
CircleTangentToTwoLinesWithRadius 50 80 320 190 85 190 125 40 30
CircleTangentToTwoDisjointCirclesWithRadius 120 200 50 210 150 30 25
CircleTangentToTwoDisjointCirclesWithRadius 100 100 80 300 250 70 50

Output for the Sample Input

(9.734940,5.801205,11.332389)
(9.113006,6.107686,5.644984)
[53.977231,160.730818]
[0.000000]
[]
[(112.047575,299.271627),(199.997744,199.328253)]
[(-0.071352,123.937211),(150.071352,256.062789)]
[(100.000000,200.000000)]
[]
[(72.231286,121.451368),(87.815122,63.011983),(128.242785,144.270867),(143.826621,85.831483)]
[(157.131525,134.836744),(194.943947,202.899105)]
[(204.000000,178.000000)]

Rujia Liu's Present 4: A Contest Dedicated to Geometry and CG Lovers
Special Thanks: Di Tang and Yi Chen

自己的代码不知道哪里错了,看别人的看的头晕。以后有时间再找到底是哪错了吧!

/*#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<vector>
using namespace std;

struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};

typedef Point Vector;
Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator *(Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator /(Vector A,double p){return Vector(A.x/p,A.y/p);}
bool operator < (const Point &a,const Point &b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
bool operator == (const Point &a,const Point &b){
    return (dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0);
}
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 Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}
double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}


Vector Rotate(Vector A,double rad)//向量旋转
{
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}

Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)//两直线的交点
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}

double DistanceToLine(Point P,Point A,Point B)//点到直线的距离
{
    Vector v1=B-A,v2=P-A;
    return fabs(Cross(v1,v2))/Length(v1);
}

double DistanceToSegment(Point P,Point A,Point B)//点到线段的距离
{
    if(A==B) return Length(P-A);
    Vector v1=B-A,v2=P-A,v3=P-B;
    if(dcmp(Dot(v1,v2)) < 0) return Length(v2);
    else if(dcmp(Dot(v1,v3)) > 0) return Length(v3);
    else return fabs(Cross(v1,v2))/Length(v1);
}

Point GetLineProjection(Point P,Point A,Point B)//P在直线上的投影点
{
    Vector v=B-A;
    return A+v*(Dot(v,P-A)/Dot(v,v));
}

bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)//两线段规范相交(不包括端点)
{
    double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
        c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}

bool OnSegment(Point p,Point a1,Point a2)//点是否在线段上
{
    return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0;
}

double PolygonArea(Point *p,int n)//多边形的有向面积
{
    double area=0;
    for(int i=1;i<n-1;i++)
        area+=Cross(p[i]-p[0],p[i+1]-p[0]);
    return area/2;
}

Point read_point()
{
    Point p;
    scanf("%lf %lf",&p.x,&p.y);
    return p;
}

double min(double a,double b)
{
    if(a-b>0.00000001) return b;
    else return a;
}

double max(double a,double b)
{
    if(a-b>0.00000001) return a;
    else return b;
}

struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point c,double r):c(c),r(r) {}
    Point point(double a){
        return Point(c.x+cos(a)*r,c.y+sin(a)*r);
    }
};

const double PI=3.141592653589793238462;
double angle(Vector v){ return atan2(v.y,v.x);} //求极角

bool mycomp(const Point &a,const Point &b)
{
    if(dcmp(a.x-b.x)!=0) return (dcmp(a.x-b.x)<0?1:0);
    else
        return (dcmp(a.y-b.y)<0?1:0);
}

void CircumscribedCircle()//求三点的外接圆(三边垂直平分线的交点)
{
    Point A,B,C,D,E,c;
    Vector v1,v2;
    double r;
    A=read_point();
    B=read_point();
    C=read_point();
    D=(B+A)/2;
    v1=Rotate(B-A,PI/2);
    E=(C+B)/2;
    v2=Rotate(C-B,PI/2);
    c=GetLineIntersection(D,v1,E,v2);
    r=Length(c-B);
    printf("(%.6lf,%.6lf,%.6lf)
",c.x+eps,c.y,r+eps);
}

void InscribedCircle()//求三角形内接圆
{
    Point A,B,C,c;
    Vector v1,v2;
    double r,ang;
    A=read_point();
    B=read_point();
    C=read_point();
    ang=Angle(C-A,B-A);
    v1=Rotate(B-A,ang/2);
    ang=Angle(A-B,C-B);
    v2=Rotate(C-B,ang/2);
    c=GetLineIntersection(A,v1,B,v2);
    r=DistanceToLine(c,A,B);
    printf("(%.6lf,%.6lf,%.6lf)
",c.x+eps,c.y+eps,r+eps);
}
void TangentLineThroughPoint()//定圆求过定点的所有切线
{
    Point P;
    Circle C;
    double ang,ang1,ang2;
    C.c=read_point();
    scanf("%lf",&C.r);
    P=read_point();
    Vector v,u=C.c-P;
    double dist=Length(u);
    if(dist<C.r)
    {
        printf("[]
");return ;
    }
    else if(dcmp(dist-C.r)==0)
    {
        v=Rotate(u,PI/2);
        ang1=angle(v);
        if(ang1<eps) ang1+=PI;
        if(PI-ang1<eps) ang1-=PI;
        printf("[%.6lf]
",ang1*180/PI);return ;
    }
    else {
        ang=asin(C.r/dist);
        v=Rotate(u,-ang);
        ang1=angle(v);
        if(ang1<eps) ang1+=PI;
        if(PI-ang1<eps) ang1-=PI;
        v=Rotate(u,ang);
        ang2=angle(v);
        if(ang1<eps) ang2+=PI;
        if(PI-ang1<eps) ang2-=PI;
        if(ang1-ang2>eps) ang=ang1,ang1=ang2,ang2=ang;
        printf("[%.6lf,%.6lf]
",eps+ang1*180/PI,eps+ang2*180/PI);return ;
    }
}
void GetLineCircleIntersection(Point c,double r,Point A,Point B,vector<Point> &cc)
{
    double dist=DistanceToLine(c,A,B);
    Vector v;
    double len,a,len1;
    Point temp;
    if(dcmp(dist-r)>0) return ;
    else if(dcmp(dist-r)==0)
    {
        cc.push_back(GetLineProjection(c,A,B));return ;
    }
    else
    {
        temp=GetLineProjection(c,A,B);
        v=B-A;
        len=Length(v);
        len1=Length(temp-c);
        a=sqrt(r*r-len1*len1);
        cc.push_back(temp+v/len*a);
        cc.push_back(temp+v/-len*a);
    }
}

void CircleThroughAPointAndTangentToALineWithRadius()//已知定点定直线定半径,求过定点的切与直线相切的圆
{
    Point P,A,B,A1,A2,B1,B2;
    double r,len;
    Vector v,v1;
    vector<Point> cc;
    P=read_point();
    A=read_point();
    B=read_point();
    scanf("%lf",&r);
    v=B-A;
    v1=Rotate(v,PI/2);
    len=Length(v1);
    A1=A+v1/len*r;
    B1=B+v1/len*r;
    A2=A+v1/-len*r;
    B2=B+v1/-len*r;
    GetLineCircleIntersection(P,r,A1,B1,cc);
    GetLineCircleIntersection(P,r,A2,B2,cc);
    sort(cc.begin(),cc.end(),mycomp);
    printf("[");
    for(int i=0;i<cc.size();i++)
    {
        if(i==0) printf("(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
        else printf(",(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
    }
    printf("]
");
}

void CircleTangentToTwoLinesWithRadius()
{
    Point A,B,A1,A2,B1,B2,C,D,C1,C2,D1,D2;
    double r,len;
    Vector v,v1;
    vector<Point> cc;
    A=read_point();
    B=read_point();
    C=read_point();
    D=read_point();
    scanf("%lf",&r);
    v=B-A;
    v1=Rotate(v,PI/2);
    len=Length(v1);
    A1=A+v1/len*r;
    B1=B+v1/len*r;
    A2=A+v1/-len*r;
    B2=B+v1/-len*r;
    v=C-D;
    v1=Rotate(v,PI/2);
    len=Length(v1);
    C1=C+v1/len*r;
    D1=D+v1/len*r;
    C2=C+v1/-len*r;
    D2=D+v1/-len*r;
    if(dcmp(fabs(Dot(A1-B1,C1-D1))-1)!=0)
    {
        cc.push_back(GetLineIntersection(A1,A1-B1,C1,C1-D1));
    }
    if(dcmp(fabs(Dot(A1-B1,C2-D2))-1)!=0)
    {
        cc.push_back(GetLineIntersection(A1,A1-B1,C2,C2-D2));
    }
    if(dcmp(fabs(Dot(A2-B2,C1-D1))-1)!=0)
    {
        cc.push_back(GetLineIntersection(A2,A2-B2,C1,C1-D1));
    }
    if(dcmp(fabs(Dot(A2-B2,C2-D2))-1)!=0)
    {
        cc.push_back(GetLineIntersection(A2,A2-B2,C2,C2-D2));
    }
    sort(cc.begin(),cc.end(),mycomp);
    printf("[");
    for(int i=0;i<cc.size();i++)
    {
        if(i==0) printf("(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
        else printf(",(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
    }
    printf("]
");
}
void CircleTangentToTwoDisjointCirclesWithRadius()
{
    Circle C1,C2;
    double r,dist,ang,t;
    Vector v,v1;
    vector<Point> cc;
    C1.c=read_point();
    scanf("%lf",&C1.r);
    C2.c=read_point();
    scanf("%lf",&C2.r);
    scanf("%lf",&r);
    v=C1.c-C2.c;
    dist=Length(v);
    if(dcmp(dist-(2*r+C1.r+C2.r))==0)
        cc.push_back(C2.c+v/dist*(C2.r+r));
    else if(dcmp(dist-(2*r+C1.r+C2.r))<0)
    {
        t= ((C2.r+r)*(C2.r+r)+dist*dist-(C1.r+r)*(C1.r+r)) /(2*(C2.r+r)*dist);
        ang=acos(t);
        v1=Rotate(v,ang);
        cc.push_back(C2.c+v1/Length(v1)*(C2.r+r));
        v1=Rotate(v,-ang);
        cc.push_back(C2.c+v1/Length(v1)*(C2.r+r));
    }
    sort(cc.begin(),cc.end(),mycomp);
    printf("[");
    for(int i=0;i<cc.size();i++)
    {
        if(i==0) printf("(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
        else printf(",(%.6lf,%.6lf)",eps+cc[i].x,eps+cc[i].y);
    }
    printf("]
");
}
int main()
{
    freopen("out.txt","w",stdout);
    map<string,int> m;
    m["CircumscribedCircle"]=1;
    m["InscribedCircle"]=2;
    m["TangentLineThroughPoint"]=3;
    m["CircleThroughAPointAndTangentToALineWithRadius"]=4;
    m["CircleTangentToTwoLinesWithRadius"]=5;
    m["CircleTangentToTwoDisjointCirclesWithRadius"]=6;
    string s;
    while(cin>>s)
    {
        switch(m[s])
        {
        case 1:CircumscribedCircle();break;
        case 2:InscribedCircle();break;
        case 3:TangentLineThroughPoint();break;
        case 4:CircleThroughAPointAndTangentToALineWithRadius();break;
        case 5:CircleTangentToTwoLinesWithRadius();break;
        case 6:CircleTangentToTwoDisjointCirclesWithRadius();break;
        default :break;
        }
    }
    return 0;
}*/
#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstdio>
using namespace std;

#define PI acos(-1.0)
#define M 100007
#define N 65736

const int inf = 0x7f7f7f7f;
const int mod = 1000000007;
const double eps = 1e-6;


struct Point
{
    double x, y;
    Point(double tx = 0, double ty = 0) : x(tx), y(ty){}
};
typedef Point Vtor;
//向量的加减乘除
Vtor operator + (Vtor A, Vtor B) { return Vtor(A.x + B.x, A.y + B.y); }
Vtor operator - (Point A, Point B) { return Vtor(A.x - B.x, A.y - B.y); }
Vtor operator * (Vtor A, double p) { return Vtor(A.x*p, A.y*p); }
Vtor operator / (Vtor A, double p) { return Vtor(A.x / p, A.y / p); }
bool operator < (Point A, Point B) { return A.x < B.x || (A.x == B.x && A.y < B.y); }
int dcmp(double x){ if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
bool operator == (Point A, Point B) { return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0; }
//向量的点积,长度,夹角
double Dot(Vtor A, Vtor B) { return (A.x*B.x + A.y*B.y); }
double Length(Vtor A) { return sqrt(Dot(A, A)); }
double Angle(Vtor A, Vtor B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
//叉积,三角形面积
double Cross(Vtor A, Vtor B) { return A.x*B.y - A.y*B.x; }
double Area2(Point A, Point B, Point C) { return Cross(B - A, C - A); }
//向量的旋转,求向量的单位法线(即左转90度,然后长度归一)
Vtor Rotate(Vtor A, double rad){ return Vtor(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad)); }
Vtor Normal(Vtor A)
{
    double L = Length(A);
    return Vtor(-A.y / L, A.x / L);
}
//直线的交点
Point GetLineIntersection(Point P, Vtor v, Point Q, Vtor w)
{
    Vtor u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v*t;
}
//点到直线的距离
double DistanceToLine(Point P, Point A, Point B)
{
    Vtor v1 = B - A;
    return fabs(Cross(P - A, v1)) / Length(v1);
}
//点到线段的距离
double DistanceToSegment(Point P, Point A, Point B)
{
    if (A == B) return Length(P - A);
    Vtor v1 = B - A, v2 = P - A, v3 = P - B;
    if (dcmp(Dot(v1, v2)) < 0) return Length(v2);
    else if (dcmp(Dot(v1, v3)) > 0) return Length(v3);
    else return fabs(Cross(v1, v2)) / Length(v1);
}
//点到直线的映射
Point GetLineProjection(Point P, Point A, Point B)
{
    Vtor v = B - A;
    return A + v*Dot(v, P - A) / Dot(v, v);
}

//判断线段是否规范相交
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
    double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
        c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
    return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
}
//判断点是否在一条线段上
bool OnSegment(Point P, Point a1, Point a2)
{
    return dcmp(Cross(a1 - P, a2 - P)) == 0 && dcmp(Dot(a1 - P, a2 - P)) < 0;
}
//多边形面积
double PolgonArea(Point *p, int n)
{
    double area = 0;
    for (int i = 1; i < n - 1; ++i)
        area += Cross(p[i] - p[0], p[i + 1] - p[0]);
    return area / 2;
}

struct Line
{
    Point p, b;
    Vtor v;
    Line(){}
    Line(Point a, Point b, Vtor v) : p(a), b(b), v(v) {}
    Line(Point p, Vtor v) : p(p), v(v){}
    Point point(double t) { return p + v*t; }
};
struct Circle
{
    Point c;
    double r;
    Circle(Point tc, double tr) : c(tc), r(tr){}
    Point point(double a)
    {
        return Point(c.x + cos(a)*r, c.y + sin(a)*r);
    }
};
//判断圆与直线是否相交以及求出交点
int getLineCircleIntersection(Line L, Circle C, double &t1, double &t2, vector<Point> &sol)
{
    //    printf(">>>>>>>>>>>>>>>>>>>>>>>>
");
    //注意sol没有清空哦
    double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
    double e = a*a + c*c, f = 2 * (a*b + c*d), g = b*b + d*d - C.r*C.r;
    double delta = f*f - 4.0*e*g;
    if (dcmp(delta) < 0) return 0;
    else if (dcmp(delta) == 0)
    {
        t1 = t2 = -f / (2.0*e);
        sol.push_back(L.point(t1));
        return 1;
    }
    t1 = (-f - sqrt(delta)) / (2.0 * e); sol.push_back(L.point(t1));
    t2 = (-f + sqrt(delta)) / (2.0 * e); sol.push_back(L.point(t2));
    return 2;
}
//判断并求出两圆的交点
double angle(Vtor v) { return atan2(v.y, v.x); }
int getCircleIntersection(Circle C1, Circle C2, vector<Point> &sol)
{
    double d = Length(C1.c - C2.c);
    // 圆心重合
    if (dcmp(d) == 0)
    {
        if (dcmp(C1.r - C2.r) == 0) return -1; // 两圆重合
        return 0; // 包含
    }

    // 圆心不重合
    if (dcmp(C1.r + C2.r - d) < 0) return 0; // 相离
    if (dcmp(fabs(C1.r - C2.r) - d) > 0) return 0; // 包含

    double a = angle(C2.c - C1.c);
    double da = acos((C1.r*C1.r + d*d - C2.r*C2.r) / (2 * C1.r*d));
    Point p1 = C1.point(a - da), p2 = C1.point(a + da);
    sol.push_back(p1);
    if (p1 == p2) return 1;
    sol.push_back(p2);
    return 2;
}
//求点到圆的切线
int getTangents(Point p, Circle C, Vtor* v)
{
    Vtor u = C.c - p;
    double dis = Length(u);
    if (dis < C.r)  return 0;
    else if (dcmp(dis - C.r) == 0)
    {
        v[0] = Rotate(u, PI / 2.0);
        return 1;
    }
    else
    {
        double ang = asin(C.r / dis);
        v[0] = Rotate(u, -ang);
        v[1] = Rotate(u, +ang);
        return 2;
    }
}
//求两圆的切线
int getCircleTangents(Circle A, Circle B, Point *a, Point *b)
{
    int cnt = 0;
    if (A.r < B.r) { swap(A, B); swap(a, b); }
    //圆心距的平方
    double d2 = (A.c.x - B.c.x)*(A.c.x - B.c.x) + (A.c.y - B.c.y)*(A.c.y - B.c.y);
    double rdiff = A.r - B.r;
    double rsum = A.r + B.r;
    double base = angle(B.c - A.c);
    //重合有无限多条
    if (d2 == 0 && dcmp(A.r - B.r) == 0) return -1;
    //内切
    if (dcmp(d2 - rdiff*rdiff) == 0)
    {
        a[cnt] = A.point(base);
        b[cnt] = B.point(base); cnt++;
        return 1;
    }
    //有外公切线
    double 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 (dcmp(d2 - rsum*rsum) == 0)
    {
        a[cnt] = A.point(base); b[cnt] = B.point(PI + base); cnt++;
    }//两条内切线
    else if (dcmp(d2 - rsum*rsum) > 0)
    {
        double 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++;
    }
    return cnt;
}
Circle CircumscribedCircle(Point A, Point B, Point C)
{
    Point tmp1 = Point((B.x + C.x) / 2.0, (B.y + C.y) / 2.0);
    Vtor u = C - tmp1;
    u = Rotate(u, PI / 2.0);
    Point tmp2 = Point((A.x + C.x) / 2.0, (A.y + C.y) / 2.0);
    Vtor v = C - tmp2;
    v = Rotate(v, -PI / 2.0);
    Point c = GetLineIntersection(tmp1, u, tmp2, v);
    double r = Length(C - c);
    return Circle(c, r);
}
Circle work2(Point p1, Point p2, Point p3) {
    Vtor v11 = p2 - p1;
    Vtor v12 = p3 - p1;
    Vtor v21 = p1 - p2;
    Vtor v22 = p3 - p2;
    double ang1 = (angle(v11) + angle(v12)) / 2.0;
    double ang2 = (angle(v21) + angle(v22)) / 2.0;
    Vtor vec1 = Vtor(cos(ang1), sin(ang1));
    Vtor vec2 = Vtor(cos(ang2), sin(ang2));
    Point O = GetLineIntersection(p1, vec1, p2, vec2);
    double r = DistanceToLine(O, p1, p2);
    return Circle(O, r);
}
vector<Point> solve4(Point A, Point B, double r, Point C)
{
    Vtor normal = Normal(B - A);
    normal = normal / Length(normal) * r;
    vector<Point> ans;
    double t1 = 0, t2 = 0;
    Vtor tA = A + normal, tB = B + normal;
    getLineCircleIntersection(Line(tA, tB, tB - tA), Circle(C, r), t1, t2, ans);
    tA = A - normal, tB = B - normal;
    getLineCircleIntersection(Line(tA, tB, tB - tA), Circle(C, r), t1, t2, ans);
    return ans;
}
vector<Point> solve5(Point A, Point B, Point C, Point D, double r)
{
    Line lines[5];
    Vtor normal = Normal(B - A) * r;
    Point ta, tb, tc, td;
    ta = A + normal, tb = B + normal;
    lines[0] = Line(ta, tb, tb - ta);
    ta = A - normal, tb = B - normal;
    lines[1] = Line(ta, tb, tb - ta);

    normal = Normal(D - C) * r;
    tc = C + normal, td = D + normal;
    lines[2] = Line(tc, td, td - tc);
    tc = C - normal, td = D - normal;
    lines[3] = Line(tc, td, td - tc);
    vector<Point> ans;
    ans.push_back(GetLineIntersection(lines[0].p, lines[0].v, lines[2].p, lines[2].v));
    ans.push_back(GetLineIntersection(lines[0].p, lines[0].v, lines[3].p, lines[3].v));
    ans.push_back(GetLineIntersection(lines[1].p, lines[1].v, lines[2].p, lines[2].v));
    ans.push_back(GetLineIntersection(lines[1].p, lines[1].v, lines[3].p, lines[3].v));
    return ans;
}
vector<Point> solve6(Circle C1, Circle C2, double r)
{
    vector<Point> vc;
    getCircleIntersection(Circle(C1.c, C1.r + r), Circle(C2.c, C2.r + r), vc);
    return vc;
}

string op;
double x[10];

int main()
{
    while (cin >> op)
    {
        if (op == "CircumscribedCircle")
        {
            for (int i = 0; i < 6; ++i) cin >> x[i];
            Circle ans = CircumscribedCircle(Point(x[0], x[1]), Point(x[2], x[3]), Point(x[4], x[5]));
            printf("(%.6lf,%.6lf,%.6lf)
", ans.c.x, ans.c.y, ans.r);
        }
        else if (op == "InscribedCircle")
        {
            for (int i = 0; i < 6; ++i) cin >> x[i];
            //            Circle ans = InscribedCircle(Point(x[0],x[1]),Point(x[2],x[3]),Point(x[4],x[5]));
            Circle ans = work2(Point(x[0], x[1]), Point(x[2], x[3]), Point(x[4], x[5]));
            printf("(%.6lf,%.6lf,%.6lf)
", ans.c.x, ans.c.y, ans.r);
        }
        else if (op == "TangentLineThroughPoint")
        {
            for (int i = 0; i < 5; ++i) cin >> x[i];
            Vtor vc[5];
            int len = getTangents(Point(x[3], x[4]), Circle(Point(x[0], x[1]), x[2]), vc);
            double tmp[5];
            for (int i = 0; i < len; ++i)
            {
                double ang = angle(vc[i]);
                if (ang < 0) ang += PI;
                ang = fmod(ang, PI);
                tmp[i] = ang * 180 / PI;
            }
            sort(tmp, tmp + len);
            printf("[");
            for (int i = 0; i < len; ++i)
            {
                printf("%.6lf", tmp[i]);
                if (i != len - 1) printf(",");
            }
            printf("]
");
        }
        else if (op == "CircleThroughAPointAndTangentToALineWithRadius")
        {
            for (int i = 0; i < 7; ++i) cin >> x[i];
            vector<Point> vc = solve4(Point(x[2], x[3]), Point(x[4], x[5]), x[6], Point(x[0], x[1]));
            sort(vc.begin(), vc.end());
            printf("[");
            for (size_t i = 0; i < vc.size(); ++i)
            {
                printf("(%.6lf,%.6lf)", vc[i].x, vc[i].y);
                if (i != vc.size() - 1) printf(",");
            }
            printf("]
");
        }
        else if (op == "CircleTangentToTwoLinesWithRadius")
        {
            for (int i = 0; i < 9; ++i) cin >> x[i];
            vector<Point> vc = solve5(Point(x[0], x[1]), Point(x[2], x[3]), Point(x[4], x[5]), Point(x[6], x[7]), x[8]);
            sort(vc.begin(), vc.end());
            printf("[");
            for (size_t i = 0; i < vc.size(); ++i)
            {
                printf("(%.6lf,%.6lf)", vc[i].x, vc[i].y);
                if (i != vc.size() - 1) printf(",");
            }
            printf("]
");
        }
        else
        {
            for (int i = 0; i < 7; ++i) cin >> x[i];
            vector<Point> vc = solve6(Circle(Point(x[0], x[1]), x[2]), Circle(Point(x[3], x[4]), x[5]), x[6]);
            sort(vc.begin(), vc.end());
            printf("[");
            for (size_t i = 0; i < vc.size(); ++i)
            {
                printf("(%.6lf,%.6lf)", vc[i].x, vc[i].y);
                if (i != vc.size() - 1) printf(",");
            }
            printf("]
");
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/xiong-/p/3390439.html