您的位置:首页 > 其它

判断圆与三角形是否有交点

2015-10-03 10:32 495 查看
#include <bits/stdc++.h>

using namespace std;

const double eps = 1e-7;

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);

}

int dcmp(double x)

{

    if (fabs(x)<eps) return 0;

    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;

}

//极角 = atan2(y,x); 单位弧度

double Dot(Vector A,Vector B)

{

    return A.x*B.x+A.y*B.y;    //cos符号一致

}

double Length(Vector A)

{

    return sqrt(Dot(A,A));

}

double Angle(Vector A,Vector B)

{

    return acos(Dot(A,B)/Length(A)/Length(B));    //向量ab的夹角,范围为在0,pi

}

double Cross(Vector A,Vector B)

{

    return A.x*B.y-A.y*B.x;    //sin符号一致

}

double Area2(Point A,Point B,Point C)

{

    return Cross(B-A,C-A);

}

Vector Rotate(Vector A,double rad)

{

    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));

}

Vector Normal(Vector A)

{

    double L = Length(A);    //法向量

    return Vector(-A.y/L,A.x/L);

}

//圆相关

struct Line

{

    Point p;

    Vector v;

    double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度)

    Line() {}

    Line(Point P, Vector v):p(P),v(v)

    {

        ang = atan2(v.y, v.x);

    }

    Point point (double t)

    {

        return Point(p+v*t);

    }

    Line Move(double d)

    {

        return Line(p + Normal(v)*d, v);    //平移

    }

    bool operator < (const Line& L) const

    {

        return ang < L.ang;

    }

};

struct Circle

{

    Point c;

    double r;

    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);

    }

};

//直线和圆的交点

int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>& 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*e*g;

    if (dcmp(delta)<0) return 0;

    if (dcmp(delta)==0)

    {

        t1 = t2 = -f/(2*e);

        sol.push_back(L.point(t1));

        return 1;

    }

    t1 = (-f-sqrt(delta))/(2*e);

    sol.push_back(L.point(t1));

    t2 = (-f+sqrt(delta))/(2*e);

    sol.push_back(L.point(t2));

    return 2;

}

int f(Point a,Point b,Circle c)

{

    Vector v = (Vector)

    {

        b.x-a.x,b.y-a.y

    };

    Line l(a,v);

    vector<Point>sol;

    double t1,t2;

    int ans = getLineCircleIntersection(l,c,t1,t2,sol);

    if (!ans) return 0;

    if (ans==1)

    {

        return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 );

    }

    else if (ans==2)

    {

        return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 )||( dcmp(t2)>=0 && dcmp(t2-1)<=0 );

    }

    return 0;

}

int main()

{

    Point o,a,b,c;

    double r;

    int T ;

    cin>>T;

    while (T--)

    {

        cin>>o.x>>o.y>>r;

        Circle C(o,r);

        cin>>a.x>>a.y;

        cin>>b.x>>b.y;

        cin>>c.x>>c.y;

        if ( f(a,b,C) || f(a,c,C)||f(b,c,C))

            puts("Yes");

        else puts("No");

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: