您的位置:首页 > 其它

51Nod 1298:圆与三角形(计算几何)

2017-08-16 19:41 357 查看
题目链接: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 <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#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<r && dis2<r && dis3<r) ///三点在圆内,一定没有交点,
printf("No\n");
else
printf("Yes\n"); ///三点中有在圆外的点,有在圆内的点。
}
return 0;
}

/*
第三组数据及其答案
30
9 3 7
-1 -3
5 -6
4 8
3 1 9
-2 -10
0 7
-5 -5
4 -7 3
7 -7
7 0
5 -1
-2 -2 2
5 -4
-3 -3
-9 2
-9 -1 8
-8 -9
-7 -4
-4 1
-5 9 4
-10 7
-2 6
-10 -8
3 -6 9
9 -5
-2 -9
-5 -1
8 -10 4
9 -4
-1 -2
0 -5
-1 6 1
8 -9
4 -6
-9 -2
6 -4 9
7 7
-1 7
-10 1
-3 3 9
2 -8
-2 5
-7 -10
-7 3 1
-8 -7
-3 9
-8 7
-1 5 3
-2 2
7 9
-3 -1
-7 1 2
-1 -8
-7 -3
9 -9
9 -3 1
9 5
5 -3
7 3
3 8 5
7 -10
-9 7
-10 7
-6 9 5
-2 4
-2 -2
3 -2
-5 -8 3
9 7
-4 -10
6 5
4 -9 2
-6 9
-10 -4
-8 -9
7 4 3
9 9
-9 -4
-2 -5
0 2 6
8 -6
9 -5
2 1
4 1 9
0 2
-2 9
-3 3
-8 -9 3
-4 -10
3 -9
7 7
7 -4 7
6 4
-1 4
-4 8
4 3 7
-3 4
-9 1
6 -1
-1 2 3
-5 -2
6 -1
3 8
-3 -4 7
6 9
-10 -3
2 -2
4 -9 2
-3 2
-2 8
-8 -10
-6 1 8
7 4
2 2
1 0
-5 7 6
1 -10
6 -2
-9 -3
*/

/*
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
No
No
Yes
Yes
Yes
No
No
No
No
Yes
No
Yes
Yes
Yes
No
No
Yes
Yes
Yes
No
Yes
No
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: