POJ 1584 A Round Peg in a Ground Hole(凸包判定&&圆在凸包内判定)

博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/39178777

A Round Peg in a Ground Hole

题目大意:按顺时针或逆时针给出多边形的顶点坐标、圆的半径及圆心坐标。

1.求多边形是否是个凸包,若不是输出“HOLE IS ILL-FORMED”。

2.如果多边形为凸包,判定圆是否在凸包内,若凸包在园内,输出“PEG WILL FIT”,若不在,输出“PEG WILL
NOT FIT”。

解题思路:这题大体思路就是用叉积判断一个多边形是不是凸包,因为没告诉给出的点是什么顺序,所以需要判断一下顺时针还是逆时针,还有就是凸包边上的要考虑。

在判断圆是否在凸包内的时候,再用一下叉积,看圆心与凸包叉积是不是一直同号就OK了,再求一下圆心到凸包的每个边的距离是否小于等于圆的半径r(注意这里是小于等于)。 大体上就这些trick,具体见代码吧。

另外放个小福利:WA的同学可以看一下http://midatl.fireduck.com/archive/2003/problems/MidAtlantic-2003/problem-D/

代码如下:

#include <stdio.h>
#include <algorithm>
#include <math.h>
const double eps = 1e-8;
using namespace std;

struct Point {
    double x, y;
} P[2000], O;

struct Line {
    Point a, b;
} ;

int dcmp(double x) {
    return x < -eps ? -1 : x > eps;
}

double xmult(Point a, Point b, Point c) {
    return (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x);
}

double Distance(Point a, Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double disptoseg(Point p, Line l){
	Point t = p;
	t.x += l.a.y-l.b.y, t.y += l.b.x-l.a.x;
	if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
		return Distance(p,l.a) < Distance(p,l.b)
             ? Distance(p,l.a) : Distance(p,l.b);
	return fabs(xmult(p, l.a, l.b))/Distance(l.a, l.b);
}

int main()
{
    int n;
    double r;
    while(~scanf("%d", &n) && n >= 3) {
        scanf("%lf%lf%lf", &r, &O.x, &O.y);
        for(int i = 0; i < n; ++i) {
            scanf("%lf%lf", &P[i].x, &P[i].y);
        }
        int Max = -2, Min = 2;
        for(int i = 1; i < n; ++i) {
            int t = dcmp(xmult(P[i], P[(i+2)%n], P[(i+1)%n]));
            Max = max(Max, t), Min = min(Min, t);
        }
        if(Max+Min != 0) {
            int flag = 2;
            for(int i = 0; i < n; ++i) {
                if(dcmp(disptoseg(O, Line{P[i], P[(i+1)%n]})-r) < 0){
                    flag--;
                    break;
                }
            }
            for(int i = 0; i < n; ++i) {
                if(Min == -1){
                    if(dcmp(xmult(P[(i+1)%n], O, P[i])) != 1) {
                        flag--;
                        break;
                    }
                }
                else {
                    if(dcmp(xmult(P[(i+1)%n], O, P[i])) != -1) {
                        flag--;
                        break;
                    }
                }
            }
            if(flag == 2) {
                printf("PEG WILL FIT\n");
            }
            else {
                printf("PEG WILL NOT FIT\n");
            }
        }
        else {
            printf("HOLE IS ILL-FORMED\n");
        }
    }

    return 0;
}
时间: 2024-12-17 18:52:12

POJ 1584 A Round Peg in a Ground Hole(凸包判定&&圆在凸包内判定)的相关文章

POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

首先判断是不是凸多边形 然后判断圆是否在凸多边形内 kuangbin的板子,但是有些地方不明白. 判断多边形不是凸多边形后,为什么用判断点是否在凸多边形内的模板交WA了,而用判断点是否在任意多边形内的模板A了 而且判断点是否在任意多边形的注释,返回值为什么又说是凸多边形~~~ POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内) #include <iostream> #include <cstdio> #inclu

poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内 + 圆是否在凸多边形内部

题目来源: http://poj.org/problem?id=1584 题意: 给一个多边形, 一个圆心以及半径. 首先判断是否为凸多边形. 如果是凸多边形, 再判断,圆是否在凸多边形内部. 分析: 1) 先判断是否为凸多边形 ,题目给出的顶点是有序的, 即顺时针或是 逆时针.用叉积方向判断. 2) 判断圆在多边形内, 首先判断 圆心是否在多边形内部, 是的话,然后再 判断 圆心到多边形 所有边的 距离d >= r , 即可. 代码如下: const int Max_N = 1005; con

poj 1584 A Round Peg in a Ground Hole(计算几何)

A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5603   Accepted: 1788 Description The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to on

POJ 1584 A Round Peg in a Ground Hole --判定点在形内形外形上

题意: 给一个圆和一个多边形,多边形点可能按顺时针给出,也可能按逆时针给出,先判断多边形是否为凸包,再判断圆是否在凸包内. 解法: 先判是否为凸包,沿着i=0~n,先得出初始方向dir,dir=1为逆时针,dir=-1为顺时针,然后如果后面有两个相邻的边叉积后得出旋转方向为nowdir,如果dir*nowdir < 0,说明方向逆转了,即出现了凹点,说明不是凸多边形. 然后判圆是否在多边形内: 先判圆心是否在多边形内,用环顾法,然后如果在之内,则依次判断圆心与每条凸包边的距离与半径的距离,如果所

POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全在n边形内部. 分析 1.判断给出了多边形是不是凸多边形. 2.判断圆包含在凸多边形中:一定要保证圆心在凸多边形里面.然后判断圆心到每条线段的距离要大于等于半径.. #include <iostream> #include <stdio.h> #include <string.h

POJ 1584 A Round Peg in a Ground Hole

先判断是不是N多边形,求一下凸包,如果所有点都用上了,那么就是凸多边形 判断圆是否在多边形内, 先排除圆心在多边形外的情况 剩下的情况可以利用圆心到每条边的最短距离与半径的大小来判断 #include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<list> #include<algorithm> us

POJ 1584 A Round Peg in a Ground Hole(点到直线距离,圆与多边形相交,多边形是否为凸)

题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部. 分3步: 1.判断是否是凸多边形 2.判断点是否在多边形内部 3.判断点到各边的距离是否大于等于半径 上代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using na

POJ 1584 A Round Peg in a Ground Hole(凸多边形判断 + 点是否在多边形内 + 点到线段的最短距离)

题目:传送门 题意:给你一个圆和一个多边形, 判断多边形是不是凸多边形,如果是,接着判断圆是否在凸多边形内部. #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #inclu

【POJ 1584】 A Round Peg in a Ground Hole (判凸包+判圆在凸包内)

[POJ 1584] A Round Peg in a Ground Hole (判凸包+判圆在凸包内) 这题题面是一大坑..长长的 明显是给我这种英语渣准备的... 大体意思是给出一个多边形的点 按顺时针或逆时针给出 判断是否为凸包 同时给出一个圆(圆心坐标+半径) 问这个圆在不在多边形内 首先顺逆时针不确定 我的做法是输入时先判断顺时针还是逆时针输入 然后统统变成逆时针来走 就是根据两种情况传入不同的枚举起点 终点 和加减(具体见代码 判凸包用建凸包的叉成法即可 既然逆时针走 那么如果是凸包