POJ 1584--A Round Peg in a Ground Hole

来源:互联网 发布:淘宝企业店铺登陆 编辑:程序博客网 时间:2024/06/05 22:02

题意:给定一多边形和一圆,问多边形是否是凸包,且圆能否放在多边形内。

  1. 判断一多边形是否是凸多边形,可以枚举连续的三点组成的两个向量的旋转方向,即向量差积的正负,看所有的旋转方向是否一致。如果有旋转方向相反的边,说明存在凹陷。此处注意的是,题目的输入可能有三点共线的情况,所以要忽略共线的情况再判断旋转方向是否一致,且一定要有旋转。
  2. 判断圆心是否在多边形内,仍然使用差积的方法,可以证明在凸包内一点P以及边AB,依次枚举差积ABXAP的符号应该是一致的,且不能存在共线即P在边上的情况。
  3. 利用圆的切线性质,如果圆心到所有边的最短距离大于等于圆的半径,则圆能放在多边形内,反之不行。

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define square(x) ((x)*(x))struct node{    float x,y;};node* vertex;node center;int vertexNum;float r;float direction(node p1,node p2,node p3)         //差积{    return (p3.x-p1.x)*(p2.y-p1.y)-(p3.y-p1.y)*(p2.x-p1.x);}bool IsConvex(){    int i;    float d,tmpD;    d = 0;    for(i = 0;i < vertexNum;i++)    {        tmpD = direction(vertex[i],vertex[i+1],vertex[i+2]);        if(d*tmpD < 0)            //只向一个方向旋转,注意三点共线情况            return false;        if(tmpD != 0)        d = tmpD;    }    if(d != 0)          //排除所有点共线的情况        return true;    else        return false;}float modulo(node p1,node p2)           //向量求模{    return sqrt(square(p2.x-p1.x)+square(p2.y-p1.y));}bool IsCenterInConvex(){    float d,tmpD;    for(int i = 0;i < vertexNum;i++)    {        tmpD = direction(vertex[i],center,vertex[i+1]);            //AB差乘AP        if(tmpD == 0||((i != 0)&&(tmpD*d < 0)))     //AP总在AB的一个方向,且不能共线            return false;        d = tmpD;    }    return true;}float calcMinDis(){    float minDis = 1e6;    float tmpDis;    int i;    for(i = 0;i < vertexNum;i++)    {        tmpDis = fabs(direction(center,vertex[i],vertex[i+1])/modulo(vertex[i],vertex[i+1]));    //点到直线距离        if(minDis > tmpDis)            minDis = tmpDis;    }    return minDis;}int main(){    int i;    while(~scanf("%d",&vertexNum)&&vertexNum >= 3)    {        scanf("%f%f%f",&r,¢er.x,¢er.y);        vertex = new node[vertexNum+2];        for(i = 0;i < vertexNum;i++)        {            scanf("%f%f",&vertex[i].x,&vertex[i].y);        }        vertex[vertexNum] = vertex[0];        vertex[vertexNum+1] = vertex[1];        if(!IsConvex())             //多边形不是凸包        {            printf("HOLE IS ILL-FORMED\n");            continue;        }        if(!IsCenterInConvex()||calcMinDis() < r)    //点在多边形外或者点到多边形距离小于圆半径        {            printf("PEG WILL NOT FIT\n");            continue;        }        printf("PEG WILL FIT\n");    }    return 0;}


0 0
原创粉丝点击