当时想的好麻烦啊.....后来突然灵光一闪有了思路。
思路如下:
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");
}
}