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>
#include <string>
#include <math.h>

#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

struct Point{
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) { }
};

const int N = 110;
const double eps = 1e-8;

int dcmp(double x) {
    if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}

Point operator + (Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
Point operator * (Point A, double p) { return Point(A.x * p, A.y * p); }
Point operator / (Point A, double p) { return Point(A.x / p, A.y / p); }
bool operator == (Point A, Point B) { return dcmp(A.x-B.x) == 0 && dcmp(A.y - B.y) == 0; }

double Cross(Point A, Point B) { /// 叉积
    return A.x * B.y - A.y * B.x;
}
double Dot(Point A, Point B) {
    return A.x * B.x + A.y * B.y; /// 点积
}
double Length(Point A) { return sqrt(Dot(A, A)); }

bool Onseg(Point p, Point a1, Point a2) { /// 判断点 p 是否在线段 a1a2 上(含端点)
    return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) <= 0;
}

bool SPI(Point a1, Point a2, Point b1, Point b2) { /// 判断线段a1a2与线段b1b2是否相交
    return
    max(a1.x,a2.x) >= min(b1.x,b2.x) &&
    max(b1.x,b2.x) >= min(a1.x,a2.x) &&
    max(a1.y,a2.y) >= min(b1.y,b2.y) &&
    max(b1.y,b2.y) >= min(a1.y,a2.y) &&
    dcmp(Cross(b1 - a2, a1 - a2)) * dcmp(Cross(b2 - a2, a1 - a2)) <= 0 &&
    dcmp(Cross(a1 - b2, b1 - b2)) * dcmp(Cross(a2 - b2, b1 - b2)) <= 0;
}

inline int isPointInpolygon(Point tmp, Point P[], int n) { /// 判断点是否在多边形里
    int wn = 0;
    rep(i, 0, n - 1) {
        if(Onseg(tmp, P[i], P[(i + 1) % n])) return -1; /// 边界
        int k = dcmp(Cross(P[(i + 1) % n] - P[i], tmp - P[i]));
        int d1 = dcmp(P[i].y - tmp.y);
        int d2 = dcmp(P[(i +1) % n].y - tmp.y);
        if(k > 0 && d1 <= 0 && d2 > 0) wn++;
        if(k < 0 && d2 <= 0 && d1 > 0) wn--;
    }
    if(wn != 0) return 1; /// 内部
    return 0; /// 外部
}
/// 判断凸多边形,允许共线,点可以是顺时针给出也可以是逆时针给出,编号0~n-1
bool isconvex(Point p[], int n) {
    bool vis[3]; mem(vis, 0);
    rep(i, 0, n - 1) {
        vis[dcmp(Cross(p[(i + 1) % n] - p[i], p[(i + 2) % n] - p[i])) + 1] = 1;
        if(vis[0] && vis[2]) return false;
    }
    return true;
}

double DistanceToSegment(Point p, Point A, Point B) { /// 求点 p 到线段 AB 的最短距离
    if(A == B) return Length(p - A);
    Point v1 = B - A, v2 = p - A, v3 = p - B;
    if(dcmp(Dot(v1, v2)) < 0) return Length(v2);
    else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);
    else return fabs(Cross(v1, v2)) / Length(v1);
}

Point P[N];

int main() {

    int n;
    double R, x, y;
    while(scanf("%d", &n) == 1) {
        if(n < 3) break;
        scanf("%lf %lf %lf", &R, &x, &y);
        rep(i, 0, n - 1)  scanf("%lf %lf", &P[i].x, &P[i].y);

        if(!isconvex(P, n)) { /// 不是凸多边形
            puts("HOLE IS ILL-FORMED");
            continue;
        }

        Point p = Point(x, y);

        if(isPointInpolygon(p, P, n) == 0) { /// 点不在多边形内部
            puts("PEG WILL NOT FIT");
            continue;
        }

        bool flag = 0;
        rep(i, 0, n - 1) { /// 判断点到线段的最短距离是否大于等于 R
            if(dcmp(fabs(DistanceToSegment(p, P[i], P[(i + 1) % n])) - R) < 0) {
                flag = 1;
                break;
            }
        }
        if(flag) puts("PEG WILL NOT FIT");
        else puts("PEG WILL FIT");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/Willems/p/12401486.html

时间: 2024-11-05 18:52:20

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

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

博客原文地址: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 WI

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 判断凸多边形 点到线段距离 点在多边形内

首先判断是不是凸多边形 然后判断圆是否在凸多边形内 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

先判断是不是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 --判定点在形内形外形上

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

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 (判凸包+判圆在凸包内)

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