1. 程式人生 > >判斷圓與三角形是否相交

判斷圓與三角形是否相交

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<vector>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e6+500;
const int M=1e4+5;
const ll INF=0x3f3f3f3f;
const int mod=1e9+7;
const double EPS = 1e-9;
const double PI = acos(-1.0);

struct Node{
    double x;
    double y;
};

double dis(Node a,Node b){//計算兩點之間距離
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

int disline(Node a,Node b,Node c,double R){//判斷在圓外的兩點形成的線段是否與圓相交
    if(c.x==b.x){//bc線段與x軸垂直
        if(abs(a.x-b.x)>R)//圓心到bc直線的距離大於半徑則不相交
            return 0;
        else{//圓心到bc直線的距離小於半徑
            if(b.y>a.y&&c.y>a.y || b.y<a.y&&c.y<a.y)//若兩點y均大於(小於)圓心的y則不相交
                return 0;
            else//其餘情況均相交
                return 1;
        }
    }
    else if(c.y==b.y){//bc線段與y軸垂直,原理同與x軸垂直
        if(abs(a.y-b.y)>R)
            return 0;
        else{
            if(b.x<a.x&&c.x<a.x || b.x>a.x&&c.x>a.x)
                return 0;
            else
                return 1;
        }
    }
    else{
        Node d;//bc直線上圓心r的垂點
        double kbc=(b.y-c.y)/(b.x-c.x);//根據公式y=kx+b,kbc為bc直線的k,bbc為其中的b,kad、bad同理
        double bbc=b.y-kbc*b.x;
        double kad=-1/kbc;
        double bad=a.y-kad*a.x;
        d.x=(bad-bbc)/(kbc-kad);
        d.y=kbc*d.x+bbc;
        if(dis(a,d)>R)//圓心到直線bc的距離大於半徑則不相交
            return 0;
        else{//圓心到直線bc的距離小於半徑
            if(d.x>b.x&&d.x>c.x || d.x<b.x&&d.x<c.x)//垂點d不線上段bc上則不相交
                return 0;
            else//其餘情況則相交
                return 1;
        }
    }

}

int solve(Node r,Node t1,Node t2,Node t3,double R){
    if(dis(r,t1)<R && dis(r,t2)<R && dis(r,t3)<R)//三點均在圓內則圓與三角形不相交
        return 0;
    //三點均在圓外,圓與三條線段均不相交,則圓與三角形不相交
    if(dis(r,t1)>R && dis(r,t2)>R && dis(r,t3)>R && !disline(r,t1,t2,R) && !disline(r,t1,t3,R) && !disline(r,t2,t3,R))
        return 0;
    return 1;
}
int main(){
    int T;
    scanf("%d",&T);
    Node r,t1,t2,t3;
    double R;
    while(T--){
        scanf("%lf%lf%lf",&r.x,&r.y,&R);
        scanf("%lf%lf",&t1.x,&t1.y);
        scanf("%lf%lf",&t2.x,&t2.y);
        scanf("%lf%lf",&t3.x,&t3.y);
        if(solve(r,t1,t2,t3,R))
            printf("Yes\n");
        else
            puts("No");
    }

    return 0;
}