poj1584 A Round Peg in a Ground Hole

来源:互联网 发布:饥荒数据修改易宁 编辑:程序博客网 时间:2024/06/06 05:32

A Round Peg in a Ground Hole
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 6454 Accepted: 2048

Description

The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to one another using a wooden peg that fits into pre-cut holes in each piece to be attached. The pegs have a circular cross-section and so are intended to fit inside a round hole.
A recent factory run of computer desks were flawed when an automatic grinding machine was mis-programmed. The result is an irregularly shaped hole in one piece that, instead of the expected circular shape, is actually an irregular polygon. You need to figure out whether the desks need to be scrapped or if they can be salvaged by filling a part of the hole with a mixture of wood shavings and glue.
There are two concerns. First, if the hole contains any protrusions (i.e., if there exist any two interior points in the hole that, if connected by a line segment, that segment would cross one or more edges of the hole), then the filled-in-hole would not be structurally sound enough to support the peg under normal stress as the furniture is used. Second, assuming the hole is appropriately shaped, it must be big enough to allow insertion of the peg. Since the hole in this piece of wood must match up with a corresponding hole in other pieces, the precise location where the peg must fit is known.
Write a program to accept descriptions of pegs and polygonal holes and determine if the hole is ill-formed and, if not, whether the peg will fit at the desired location. Each hole is described as a polygon with vertices (x1, y1), (x2, y2), . . . , (xn, yn). The edges of the polygon are (xi, yi) to (xi+1, yi+1) for i = 1 . . . n − 1 and (xn, yn) to (x1, y1).

Input

Input consists of a series of piece descriptions. Each piece description consists of the following data:
Line 1 < nVertices > < pegRadius > < pegX > < pegY >
number of vertices in polygon, n (integer)
radius of peg (real)
X and Y position of peg (real)
n Lines < vertexX > < vertexY >
On a line for each vertex, listed in order, the X and Y position of vertex The end of input is indicated by a number of polygon vertices less than 3.

Output

For each piece description, print a single line containing the string:
HOLE IS ILL-FORMED if the hole contains protrusions
PEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated position
PEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated position

Sample Input

5 1.5 1.5 2.01.0 1.02.0 2.01.75 2.01.0 3.00.0 2.05 1.5 1.5 2.01.0 1.02.0 2.01.75 2.51.0 3.00.0 2.01

Sample Output

HOLE IS ILL-FORMEDPEG WILL NOT FIT

又是看了半个小时的题意,愣是没搞懂什么意思QAQ,看了别人的博客表示懂了意思,不过他们写的代码感觉好长,于是我自己直接想了一些简单的方法来做辣\(^o^)/

题意:顺时针或者逆时针依次给你n个点,然后你需要判断这是不是一个凸包。如果是继续向下判断以o点为圆心的圆是不是完全在凸包里面。

1.判断凸包。当然是利用叉积(话说这都是定理了吧)凸包相邻两个向量之间有一个特点,那就是叉积方向相同。


通过图片也不难看出,凸包会呈现出一种龙卷风的样子,围绕着中心靠拢,而出现凹的地方必定会向外拐一次。

2.判断圆是不是完全在凸包里面,我们可以先判断圆心是不是在凸包里面,如果不是,就不用继续判断了。如果在里面,我们只需要判断圆心到凸包上线段的距离是不是都大于圆的半径就可以了。

3.首先是判断圆心是不是在凸包里面。看了有的博客用了麻烦的方法,这里其实用叉积就可以判断。


如果圆心在凸包里面(左图),很明显圆心和凸包顶点组成的那些向量(连线箭头)相邻的向量之间叉积符号相同,这里不难想,因为如果圆心在凸包里面的话,向量肯定是像转风车一样转的(按照一个方向走)。

而如果不再里面(右图)就会出现向反方向走的情况我画的图就是顶上的两个向量内拐了。(读者可以自己画画看看加深理解)。

4.判断圆心到凸包的距离是不是都大于半径。

还是利用叉积(计算几何就是这个来回用啊),看上面的左图,红线的h就是需要我们求的距离,那么我们可以先利用叉积求出三角形的面积,然后除去底就可以辣。

最后不要忘记封闭多边形,方面枚举。

博主表示自己画的图看上去还不错对吧qwq

#include <iostream>#include <cmath>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAXN=1000+10;double eps=1e-5;struct node{    double x,y;}point[MAXN],o;//o为圆心int n;double r,px,py;int cmp(double x)//做计算几何的题一定要考虑精度{    if(fabs(x)<=eps)return 0;    return x<0?-1:1;}double chaji(double x1,double y1,double x2,double y2){    return x1*y2-x2*y1;}double cross(node a,node b,node c,node d)//计算AB×(叉乘)CD{    return chaji(b.x-a.x,b.y-a.y,d.x-c.x,d.y-c.y);}bool check_tubao()//检查是否为凸包{    int d=0,temp;    for(int i=0;i<n;++i)    {        temp=cmp(cross(point[i],point[i+1],point[i+1],point[i+2]));        if(!d)d=temp;        if(d*temp<0)return 0;    }    return 1;}bool check_inside()//检查圆心是不是在凸包里面{    int d=0,temp;    for(int i=0;i<n;++i)    {        temp=cmp(cross(o,point[i],o,point[i+1]));        if(!d)d=temp;        if(d*temp<=0)return 0;    }    return 1;}double get_dist(node a,node b)//计算圆心到线段ab的距离{    return fabs(cross(o,a,o,b))/hypot(a.x-b.x,a.y-b.y);}bool check_dist()//检查圆是不是全部在凸包里面{    for(int i=0;i<n;++i)    {        if(cmp(get_dist(point[i],point[i+1])-r)<0)return 0;    }    return 1;}int main(){    int i;    while(~scanf("%d",&n)&&n>=3)    {        scanf("%lf%lf%lf",&r,&o.x,&o.y);        for(i=0;i<n;++i)scanf("%lf%lf",&point[i].x,&point[i].y);        point[n]=point[0];        point[n+1]=point[1];        if(!check_tubao())        {            printf("HOLE IS ILL-FORMED\n");            continue;        }        if(check_inside()&&check_dist())        {            printf("PEG WILL FIT\n");        }        else printf("PEG WILL NOT FIT\n");    }    return 0;}



1 0
原创粉丝点击