题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298
题目给出一个圆的圆心坐标和半径,再给出三角形三点坐标。判断三角形与圆是否相交,相交的话输出Yes,相离输出No.
非常简单的一个几何题目。
很容易想到如果三角形三点距圆心的距离都小于半径,则三角形在圆内,没有交点。
如果三角形三点距圆心的距离都大于半径,此时圆心到三角形三边的距离要大于半径。
不过做的时候WA到吐血,狂WA第三组测试数据,奔溃掉。
然后百度别人的博客想看看自己坑到哪里了,发现他们先求直线方程又求焦点,又判断
焦点是否在线段上,然后再弄。好麻烦的做法,直接用点到线段距离公式不就好了,看
不下去了,后来无奈把第三组数据的输入和输出都下载下来了,一侧才发现,其中有一
组相切的情况,竟然给我判了相离,才发现计算过程更中精度缺失,所以加了个eps,
距离减去r>eps,才判距离大于半径。才过了。
用点到线段距离做炒鸡简单的。求法如图所示:
声明:以下求法只针对三点构成三角形的情况,并没有去考虑,AB非常近,或ABP三点共线这种
情况。
代码模板:
///求点到线段的最短距离。
double getNearestDistance(double x1,double y1,double x2,double y2,double x,double y)
{
double a = getDistance(x1,y1,x,y);
double b = getDistance(x2,y2,x,y);
double c = getDistance(x1,y1,x2,y2);
if(a*a>=b*b+c*c)
return b;
if(b*b>=a*a+c*c)
return a;
double L = (a+b+c)/2;
double S = sqrt(L*(L-a)*(L-b)*(L-c));
return 2*S/c;
}
题目AC代码:
#include
#include
#include
#include
#define eps 1e-6
using namespace std;
///求两点直接距离。
double getDistance(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
///求点到线段的最短距离。
double getNearestDistance(double x1,double y1,double x2,double y2,double x,double y)
{
double a = getDistance(x1,y1,x,y);
double b = getDistance(x2,y2,x,y);
double c = getDistance(x1,y1,x2,y2);
if(a*a>=b*b+c*c)
return b;
if(b*b>=a*a+c*c)
return a;
double L = (a+b+c)/2;
double S = sqrt(L*(L-a)*(L-b)*(L-c));
return 2*S/c;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
double x,y,r; ///圆心和半径
double x1,y1,x2,y2,x3,y3; ///三角形三点坐标
double dis1,dis2,dis3,dis4,dis5,dis6;
scanf("%lf%lf%lf",&x,&y,&r);
scanf("%lf%lf",&x1,&y1);
scanf("%lf%lf",&x2,&y2);
scanf("%lf%lf",&x3,&y3);
dis1 = getDistance(x,y,x1,y1); ///点1到圆心的距离
dis2 = getDistance(x,y,x2,y2); ///点2到圆心的距离
dis3 = getDistance(x,y,x3,y3); ///点3到圆心的距离
dis4 = getNearestDistance(x1,y1,x2,y2,x,y); ///圆心到点1点2组成线段的距离
dis5 = getNearestDistance(x1,y1,x3,y3,x,y); ///圆心到点1点3组成线段的距离
dis6 = getNearestDistance(x2,y2,x3,y3,x,y); ///圆心到点2点3组成线段的距离
/*不用epsWA到死*/
if(dis4-r>eps && dis5-r>eps && dis6-r>eps) ///三点在圆外且圆心到三角形三边距离大于r,没交点
printf("No\n");
else if(dis1