[POJ1584]A Round Peg in a Ground Hole(计算几何-凸多边形)

题目:

我是超链接

题意:

给出一个半径R、一个点O、顺时针或者逆时针给出一个多边形
首先判断多边形是否为凸多边形,如果不是输出HOLE IS ILL-FORMED
然后再判断以O为圆心以R为半径的圆是否完全在多边形里,是则输出PEG WILL FIT,否则输出PEG WILL NOT FIT

题解:

这个判断是否为凸多边形的话,考虑ta们的特点:任取一条边, 整个图形都在这条边所在直线的一侧.
这个圆呢?用射线法看看圆心O在不在多边形里,然后顺便计算disTL满足条件就好(点到线的距离)
这里写图片描述
—–图截选自Enzymii
1A啦

代码:

#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-9;
int n;
int dcmp(double x)
{
    if (x<=eps && x>=-eps) return 0;
    return (x>0)?1:-1;
}
struct po
{
    double x,y;
    po(double X=0,double Y=0){x=X;y=Y;}
}dian[100005];
po operator -(po x,po y){return po(x.x-y.x,x.y-y.y);}
double cj(po x,po y){return x.x*y.y-x.y*y.x;}
double dot(po x,po y){return x.x*y.x+x.y*y.y;}
double len(po x){return sqrt(dot(x,x));}
double disTL(po p,po a,po b)
{
    po v=b-a,w=p-a;
    return fabs(cj(v,w)/len(v));
}
bool PInP(po p,double R)
{
    int cnt=0,a,b,c;
    for (int i=1;i<=n;i++)
    {
        if (dcmp(disTL(p,dian[i],dian[i%n+1])-R)<0) return 0;
        a=dcmp(cj(dian[i%n+1]-dian[i],p-dian[i]));
        b=dcmp(dian[i].y-p.y);
        c=dcmp(dian[i%n+1].y-p.y);
        if (a>0 && b<=0 && c>0) ++cnt;
        if (a<0 && b>0 && c<=0) --cnt;
    }
    if (cnt) return 1;
    return 0;
}
int main()
{
    while (scanf("%d",&n) && n>=3)
    {
        double r,x,y;bool fff=1;po p;
        scanf("%lf%lf%lf",&r,&x,&y),p=po(x,y);
        for (int i=1;i<=n;i++) scanf("%lf%lf",&x,&y),dian[i]=po(x,y);
        int fx=0;
        for (int i=1;i<n;i++) 
        {
            int t=dcmp(cj(dian[i%n+1]-dian[i],dian[(i+1)%n+1]-dian[i]));
            if (t) 
            {
                if (!fx) fx=t;else if (fx!=t) {fff=0;break;}
            }
        }
        if (!fff) printf("HOLE IS ILL-FORMED\n");
        else 
        {
            if (!PInP(p,r)) printf("PEG WILL NOT FIT\n");
            else printf("PEG WILL FIT\n");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值