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

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298

题目给出一个圆的圆心坐标和半径,再给出三角形三点坐标。判断三角形与圆是否相交,相交的话输出Yes,相离输出No.

非常简单的一个几何题目。

很容易想到如果三角形三点距圆心的距离都小于半径,则三角形在圆内,没有交点。

如果三角形三点距圆心的距离都大于半径,此时圆心到三角形三边的距离要大于半径。

不过做的时候WA到吐血,狂WA第三组测试数据,奔溃掉。

51Nod 1298:圆与三角形(计算几何)_第1张图片

然后百度别人的博客想看看自己坑到哪里了,发现他们先求直线方程又求焦点,又判断

焦点是否在线段上,然后再弄。好麻烦的做法,直接用点到线段距离公式不就好了,看

不下去了,后来无奈把第三组数据的输入和输出都下载下来了,一侧才发现,其中有一

组相切的情况,竟然给我判了相离,才发现计算过程更中精度缺失,所以加了个eps,

距离减去r>eps,才判距离大于半径。才过了。


用点到线段距离做炒鸡简单的。求法如图所示:

声明:以下求法只针对三点构成三角形的情况,并没有去考虑,AB非常近,或ABP三点共线这种

情况。

51Nod 1298:圆与三角形(计算几何)_第2张图片

代码模板:

///求点到线段的最短距离。
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



你可能感兴趣的:(ACM_数论,Online,Judge,51Nod)