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

来源:互联网 发布:时间浪人网络大电影 编辑:程序博客网 时间:2024/06/17 11:12

题目链接: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-6using 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;}/*第三组数据及其答案309 3 7-1 -35 -64 83 1 9-2 -100 7-5 -54 -7 37 -77 05 -1-2 -2 25 -4-3 -3-9 2-9 -1 8-8 -9-7 -4-4 1-5 9 4-10 7-2 6-10 -83 -6 99 -5-2 -9-5 -18 -10 49 -4-1 -20 -5-1 6 18 -94 -6-9 -26 -4 97 7-1 7-10 1-3 3 92 -8-2 5-7 -10-7 3 1-8 -7-3 9-8 7-1 5 3-2 27 9-3 -1-7 1 2-1 -8-7 -39 -99 -3 19 55 -37 33 8 57 -10-9 7-10 7-6 9 5-2 4-2 -23 -2-5 -8 39 7-4 -106 54 -9 2-6 9-10 -4-8 -97 4 39 9-9 -4-2 -50 2 68 -69 -52 14 1 90 2-2 9-3 3-8 -9 3-4 -103 -97 77 -4 76 4-1 4-4 84 3 7-3 4-9 16 -1-1 2 3-5 -26 -13 8-3 -4 76 9-10 -32 -24 -9 2-3 2-2 8-8 -10-6 1 87 42 21 0-5 7 61 -106 -2-9 -3*//*YesYesYesYesYesYesYesNoNoNoYesYesYesNoNoNoNoYesNoYesYesYesNoNoYesYesYesNoYesNo*/



原创粉丝点击