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

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;
/*
计算几何
给定圆心坐标、圆半径,三角形三个顶点坐标,判断圆是否与三角形相交
*/
const double esp=1e-7;

int sgn(double x)
{
    if(fabs(x)<esp) return 0;
    if(x<0) return -1;
    else return 1;
}
struct Point
{
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {
        x=_x;
        y=_y;
    }
    Point operator -(const Point &b) const
    {
        return Point(x-b.x,y-b.y);
    }
    double operator ^ (const Point &b) const//叉积
    {
        return x*b.y-y*b.x;
    }
    double operator * (const Point &b) const//点积
    {
        return x*b.x+y*b.y;
    }
    double distance(Point p)//两点距离
    {
        return hypot(x-p.x,y-p.y);
        //return (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y);
    }
};
struct Line
{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e)
    {
        s=_s;
        e=_e;
    }
    double length()//线段长度
    {
        return s.distance(e);
    }
    double dispointtoline(Point p)//点到直线距离
    {
        return fabs((p-s)^(e-s))/length();
    }
    double dispointtoseg(Point p)//点到线段距离
    {
        if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)
            return min(p.distance(s),p.distance(e));
        return dispointtoline(p);
    }

};


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        Point c,t[3];
        double r;

        scanf("%lf %lf %lf",&c.x,&c.y,&r);
        for(int i=0; i<3; i++)
        {
            scanf("%lf %lf",&t[i].x,&t[i].y);
        }
        Line line[3];
        line[0]=Line(t[0],t[1]);
        line[1]=Line(t[0],t[2]);
        line[2]=Line(t[1],t[2]);

        double cnt[3];

        for(int i=0; i<3; i++)//圆心到三角形各边的距离
        {
            cnt[i]=line[i].dispointtoseg(c)-r;
            //cout<<cnt[i]<<endl;
        }
        //圆心到三角形各边的距离都大于半径
        if(sgn(cnt[0])>0&&sgn(cnt[1])>0&&sgn(cnt[2])>0)
        {
            printf("No\n");
        }
        //圆心到三角形各边的距离都小于半径
        else if(sgn(cnt[0])<0&&sgn(cnt[1])<0&&sgn(cnt[2])<0)//
        {
            bool flag=0;
            for(int i=0;i<3;i++)//圆心到三角形各顶点的距离
            {
                if(sgn(t[i].distance(c)-r)>=0)
                {
                    flag=1;
                    break;
                }
            }
            if(flag)
            {
                printf("Yes\n");
            }
            else
            {
                printf("No\n");
            }
        }
        else
        {
            printf("Yes\n");
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值