这几天又没怎么学习,懒癌末期啊真的是。
被一道圆与三角形的基础题难倒了,很烦,发现自己数学不好。
这个问题牵扯到线段和点的距离判断。
分三种情况
1. 点P到直线的距离等于点P到端点A的距离。
2. 点P到直线的距离等于点P到端点B的距离。
3. 点P到直线的距离等于点P到投影点C的距离。
设向量AP,向量AB。
AP与AB的余弦cos=AP·AB/|AP||AB|
若cos<0则是第一种情况了 我们return AP;
else 我们进行下一步运算
{
AC=AP*cos;
if(AC>AB)
return PB;
else
return PC;
}
然后找到圆心与三条边的最大值与最小值
if((max>r&&max<r)||max==r||min==r)
就YES啊
else就NO咯
然后悲剧地发现WA了
因为没有想到如果三条边与圆心的距离都小于r,但三个顶点与圆心的距离大于r的情况。
加进去,再交,再WA。
就很气。
检查数据之后发现这种几何题目需要加入精度控制。
于是又写了一个sgn
int sgn(double a)
{
return a<-eps?-1:a<eps?0:1;
}
千辛万苦终于是AC了
//#define Debug
#include <stdio.h>
#include <math.h>
#define MAXN 100001
#define INF 0x3f3f3f3f
#define MIN(a,b) a>b?b:a
#define MAX(a,b) a>b?a:b
#define eps 1e-6
int cx,cy,r;
int x[3],y[3];
int sgn(double a)
{
return a<-eps?-1:a<eps?0:1;
}
double f(double a)
{
return a*a;
}
double point(int i)
{
return sqrt((x[i]-cx)*(x[i]-cx)+(y[i]-cy)*(y[i]-cy));
}
double line(int a,int b)
{
double apl=point(a),abl=sqrt(f(x[a]-x[b])+f(y[a]-y[b]));
double cos=((cx-x[a])*(x[b]-x[a])+(y[b]-y[a])*(cy-y[a]))/apl/abl;
if(cos<=0)
{
return apl;
}
else
{
double acl=apl*cos;
if(acl>abl)
return point(b);
else
return sqrt(f(apl)-f(acl));
}
}
int main()
{
#ifdef Debug
freopen("C:\\Users\\Yemor\\Desktop\\read.txt","r",stdin);
#endif
int T;
double min,max,tmp;
scanf("%d",&T);
while(T--)
{
min=INF;
max=-INF;
scanf("%d%d%d",&cx,&cy,&r);
for (int i = 0; i < 3; ++i)
{
scanf("%d%d",&x[i],&y[i]);
}
for (int i = 0; i < 3; ++i)
{
tmp=point(i);
max=MAX(max,tmp);
}
for (int i = 0; i < 3; ++i)
{
if(i!=2)
{
tmp=line(i,i+1);
}
else
{
tmp=line(i,0);
}
min=MIN(min,tmp);
max=MAX(max,tmp);
}
if((sgn(max-r)>0&&sgn(min-r)<0)||sgn(max-r)==0||sgn(min-r)==0)
printf("%s\n","Yes" );
else
printf("%s\n","No" );
}
return 0;
}