51nod 圆与三角形

来源:互联网 发布:pg光学磨床编程 编辑:程序博客网 时间:2024/05/02 02:20

当时想的好麻烦啊.....后来突然灵光一闪有了思路。


思路如下:


1逐个判断相邻两点组成的线是否与圆有交点


2 对于任意的一条线,如果两端点只有一个在圆内则有交点

3 对于任意的一条线,如果两个端点都在圆内则没有交点

4 对于任意的一条线,如果两个端点都在圆外,则计算两端点与圆心构成的角是否有钝角,如果有则没有交点

5 对于任意的一条线,作垂线,如果半径长与垂线则有交点,否则没有交点。

ps:如何判断半径和垂线哪个长呢?

很简单:我们假设半径为r,两端点到圆心长度分别为t1,t2,两端点距离t3;那么,如果二者相切,则sqrt(t1*t1-r*r)+sqrt(t2*t2-r*r)就等于t3,如果相交则小于,否则大于。


代码如下:

#include <stdio.h>#include <algorithm>#include <string.h>#include <math.h>#include <iostream>using namespace std;int x,y,r,dian[5][2],ok;int find_ans(int x1,int y1,int x2,int y2){    double temp1=sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));    double temp2=sqrt((x2-x)*(x2-x)+(y2-y)*(y2-y));    double temp3=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));    if((temp1>r)^(temp2>r)){        printf("Yes\n");//printf("%lf(%d %d) %lf\n",temp1,x1,y1,temp2);        ok=1;        return 0;    }    else if (temp1<r && temp2<r){        return 0;    }    else {        double t1,t2;        t1=max(temp1,temp2);        t2=min(temp1,temp2);        double temp=t2*t2+temp3*temp3-t1*t1;        if(temp<0)return 0;        if(temp>0){            t1=sqrt(temp1*temp1-r*r);            t2=sqrt(temp2*temp2-r*r);            if((t1+t2)>temp3)return 0;            else {                printf("Yes\n");                ok=1;                return 0;            }        }    }}int main(){    int test;    cin>>test;    while(test--){        scanf("%d%d%d",&x,&y,&r);        for(int i=1;i<=3;i++)cin>>dian[i][0]>>dian[i][1];        dian[4][0]=dian[1][0];        dian[4][1]=dian[1][1];        ok=0;        for(int i=1;i<=3;i++){            if(!ok)find_ans(dian[i][0],dian[i][1],dian[i+1][0],dian[i+1][1]);        }        if(!ok)printf("No\n");    }}


0 0
原创粉丝点击