POJ 1584 判断凸包,点在多边形内外,点到直线最短距离

题意求给出一个多边形,问这个多边形是否是凸包,如果不是数出HOLE IS ILL-FORMED,如果是问一个棍子能否穿过,给出底面的圆心和半径。

分3步:

1、判断是否是凸多边形

2、判断点是否在多边形内部

3、判断点到各边的最小距离是否大于等于半径

由于输入是按照顺时针或者逆时针,所以只要判断相邻叉积同号就可以。。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double PointType;
struct point
{
    PointType x,y;
};
point data[160];
PointType Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线
{
    return (pj.x-pi. x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y);
}
PointType Dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int Graham_Scan(point *a,int numa)
{
    for(int i=0; i<numa; i++)
        if(Direction(a[i],a[(i+1)%numa],a[(i+2)%numa])*Direction(a[(i+1)%numa],a[(i+2)%numa],a[(i+3)%numa])<0)
            return 0;
    return 1;
}
bool On_Segment(point pi,point pj,point pk)
{
    if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))
        return 1;
    return 0;
}
bool Segment_Intersect(point p1,point p2,point p3,point p4)
{
    PointType d1=Direction(p3,p4,p1),d2=Direction(p3,p4,p2),d3=Direction(p1,p2,p3),d4=Direction(p1,p2,p4);
    if(((d1>0&&d2<0)||(d1<0&&d2>0))&&((d3>0&&d4<0)||(d3<0&&d4>0)))
        return 1;
    if(d1==0&&On_Segment(p3,p4,p1))
        return 1;
    if(d2==0&&On_Segment(p3,p4,p2))
        return 1;
    if(d3==0&&On_Segment(p1,p2,p3))
        return 1;
    if(d4==0&&On_Segment(p1,p2,p4))
        return 1;
    return 0;
}
int Pandingdian(point a,int n,point *polygon)//1在多边形上 2在多边形外 0在多边形内
{
    point b;
    b.x=-9999999;
    b.y=a.y;
    int sum=0;
    polygon[n]=polygon[0];
    for(int i=1; i<=n; i++)
        if(polygon[i].y-polygon[i-1].y!=0&&Segment_Intersect(a,b,polygon[i],polygon[i-1]))
        {
            if(Direction(a,polygon[i],polygon[i-1])==0)
                return 1;
            sum++;
        }
    if(sum&1)
        return 0;
    return 2;
}
double DotProduct(point p0,point p1,point p2)
{
    return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
double MinDistance(point p0,point p1,point p2)
{
    double d=Dis(p1,p2);
    double u=DotProduct(p1,p0,p2)/(d*d);
    if(u<0)
        return Dis(p0,p1);
    else if(u>1)
        return Dis(p0,p2);
    else
    {
        point v;
        v.x=p1.x+u*(p2.x-p1.x);
        v.y=p1.y+u*(p2.y-p1.y);
        return Dis(p0,v);
    }
}
int main()
{
    point center;
    double bj;
    int n;
    while(~scanf("%d",&n),n>2)
    {
        scanf("%lf%lf%lf",&bj,¢er.x,¢er.y);
        for(int i=0; i<n; i++)
            scanf("%lf%lf",&data[i].x,&data[i].y);
        if(!Graham_Scan(data,n))
        {
            puts("HOLE IS ILL-FORMED");
            continue;
        }
        if(Pandingdian(center,n,data))
        {
            puts("PEG WILL NOT FIT");
            continue;
        }
        int f=1;
        for(int i=0; i<n; i++)
            if(MinDistance(center,data[i],data[(i+1)%n])<bj)
            {
                f=0;
                break;
            }
        if(f)
            puts("PEG WILL FIT");
        else
            puts("PEG WILL NOT FIT");
    }
    return 0;
}
时间: 2024-10-30 03:13:36

POJ 1584 判断凸包,点在多边形内外,点到直线最短距离的相关文章

HDU 1756 判断点在多边形内外

题意:判断点在多边形内外,用来试模版的 #include <iostream> #include <stdio.h> #include <math.h> typedef double DIY; const DIY EPS = 0; const DIY N = 1000005; using namespace std; struct Point { DIY x,y; }; struct Segment { Point a; Point b; }; typedef Poin

判断点是否在多边形内部

如何判断一个点是否在多边形内部? (1)面积和判别法:判断目标点与多边形的每条边组成的三角形面积和是否等于该多边形,相等则在多边形内部. (2)夹角和判别法:判断目标点与所有边的夹角和是否为360度,为360度则在多边形内部. (3)引射线法:从目标点出发引一条射线,看这条射线和多边形所有边的交点数目.如果有奇数个交点,则说明在内部,如果有偶数个交点,则说明在外部. 具体做法:将测试点的Y坐标与多边形的每一个点进行比较,会得到一个测试点所在的行与多边形边的交点的列表.在下图的这个例子中有8条边与

OpenCV 判断点是否在多边形内

OpenCV 判断点是否在多边形内 目的 在这个教程中我们将学习如何使用 OpenCV 函数 pointPolygonTest 代码 详细代码如下 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h> using

POJ 1410 判断线段相交点在多边形内外

题意:判断一线段与矩形是否相交.需要注意的是输入可能不是按照左上右下的顺序,如果线段两个端点都在举行内的话也算相交. 这题分为判断线段与4边是否有交点,如果没有判断两点是否在矩形内就可以了.我用的方法是射线法. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef double PointType; str

POJ 2398 判断点在多边形内外

题意:给出一个矩形,再给出n条两端点分别在上下边的线段,然后给出m个点,要求按每个区域内的点数的升序输出点数t,后面为区域内有t的区域数. 这题按照题意做注意要对矩形内的边排序然后再二分判断点在那个区域里. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct point { double x,y; }; s

POJ 3449 判断多边形相交

题意:给你多边形 让你判断每个多边形分别有几个多边形与它相交. 这题的输入输出恶心,另外给出正方形对角点求出另两个点的公式 已知一正方形两对角顶点A.C的坐标分别是(ax, ay).(cx, xy): 求B.D坐标(bx, by).(dx, dy):           bx = (cx+ax+cy-ay)/2;           by = (cy+ay+ax-cx)/2;           dx = (cx+ax+ay-cy)/2;           dy = (cy+ay+cx-ax)

POJ 2318 判定点在多边形内外(二分)

题意:图片是一个俯视图,按照从左到右的顺序输入边 然后输入点坐标,问从左到右的各个区域分别有多少玩具. 已知顺序只需要二分来确定区间,然后得出结果. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct point { double x,y; }; struct edge { point up,down; }

POJ 3348 求凸包面积

题意给出n个点求凸包,然后求出凸包面积就可以. 模板题求出凸包后用叉积求出面积就可以了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef int PointType; struct point { PointType x,y; int num; }; poi

POJ 3528 &amp;amp; POJ 2974 三维凸包

题意:给出n个点,求三维凸包及其表面积. 下面这个模板从NOI选手的资料中拿到的,特别短,用的是卷包裹法,不过貌似必须保证四点不共面,要不就会出错. POJ 3528 #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<vector> #include<map> #include&