码迷,mamicode.com
首页 > 其他好文 > 详细

1298 圆与三角形

时间:2017-11-18 23:45:23      阅读:457      评论:0      收藏:0      [点我收藏+]

标签:ini   else   输入数据   nbsp   efi   text   端点   技术   point   

给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。

 
技术分享图片
技术分享图片
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 10000),之后每4行用来描述一组测试数据。
4-1:三个数,前两个数为圆心的坐标xc, yc,第3个数为圆的半径R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000)
4-2:2个数,三角形第1个点的坐标。
4-3:2个数,三角形第2个点的坐标。
4-4:2个数,三角形第3个点的坐标。(-3000 <= xi, yi <= 3000)
Output
共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。
Input示例
2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5
Output示例
Yes
No
/*
   圆与三角形是否相交,转化为线段与圆相交

   1.两点都在圆内  --相离
   2.一点在圆内,一点在圆外  --相交
   3.两点都在圆外
    ① .如果圆心到线段所在直线的距离>r  --相离
    ② .距离<=r
     如果圆心与线段两个端点以及线段本身组成的夹角都是锐角   --相交
     否则  --相离
 */
#include <bits/stdc++.h>

#define MAXK 5

using namespace std;

struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x=_x;
        y=_y;
    }
};
int t;
double a,b,r;
Point p[MAXK],O;
bool ok;

int judge(Point *p1, Point *p2,double r) {//点p1和p2都不在圆内
    double a, b, c, dist1, dist2, angle1, angle2; // ax + by + c = 0;
    if (p1->x == p2->x)
        a = 1, b = 0, c = -p1->x;//特殊情况判断,分母不能为零
    else if (p1->y == p2->y)
        a = 0, b = 1, c = -p1->y;//特殊情况判断,分母不能为零
    else {
        a = p1->y - p2->y;
        b = p2->x - p1->x;
        c = p1->x * p2->y - p1->y * p2->x;
    }
    dist1 = a * O.x + b * O.y + c;
    dist1 *= dist1;
    dist2 = (a * a + b * b) * r * r;
    if (dist1 > dist2) return 0;//点到直线距离大于半径r
    angle1 = (O.x - p1->x) * (p2->x - p1->x) + (O.y - p1->y) * (p2->y - p1->y);
    angle2 = (O.x - p2->x) * (p1->x - p2->x) + (O.y - p2->y) * (p1->y - p2->y);
    if (angle1 > 0 && angle2 > 0) return 1;//余弦都为正,则是锐角
    return 0;
}

inline void init(){
    ok=false;
}

int main(){
//    freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--){
        init();
        scanf("%lf%lf%lf",&a,&b,&r);
        O.x=a;
        O.y=b;
        int flag1=0;//圆上
        int flag2=0;//圆外
        int flag3=0;//圆内
        for(int i=0;i<3;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            if((a-p[i].x)*(a-p[i].x)+(b-p[i].y)*(b-p[i].y)==r*r)
                flag1++;
            else if((a-p[i].x)*(a-p[i].x)+(b-p[i].y)*(b-p[i].y)>r*r)
                flag2++;
            else 
                flag3++;
        }
        if(flag1!=0){//有在圆上的
            puts("Yes");
            continue;
        }else if(flag2!=0&&flag3!=0){//有在内也有在外的
            puts("Yes");
            continue;
        }else if(flag2==0&&flag3!=0){//全部在圆内
            puts("No");
            continue;
        }else{//都在圆外就要讨论了
            for(int i=0;i<3;i++){
                if(judge(&p[i%3],&p[(i+1)%3],r)==true){
                    ok=true;
                    break;
                }
            }
            if(ok==false){
                puts("No");
            }else{
                puts("Yes");
            }
        }
    }
    return 0;
}

 

1298 圆与三角形

标签:ini   else   输入数据   nbsp   efi   text   端点   技术   point   

原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/7858079.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!