点在多边形内算法——判断一个点是否在一个复杂多边形的内部

假设我们有一个多边形由n个点组成Pn={p1,p2,p3,p4,p5...pn} , 求一个点p(x,y)是否在多边形内?
在图形编程中,坐标的利用是不可忽视的。在这里判断一个点是否在多边行内部(可以包括线上)就要利用到各个点的坐标关系。

最简单的方法是使用射线法,因为它能适用于所有类型的多边形,不用考虑特殊的情况而且速度也比较快。该算法的思想很简单:在多边形外面任意一点画一条虚拟的射线到p(x,y)然后计算该射线与多边形上的边相交的次数。如果该次数是偶数,说明p(x,y)在多边形外,如果是奇数,则在多边形内。

题目:zzuoj 1245

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
#define maxn  110

double x0,yy0;
int n,m;
double x[maxn],y[maxn];

bool contains(double x0,double yy0)
{
    int crossings = 0;
    for(int i = 0;i < m;i++)
    {
        bool cond1 = (x[i] <= x0) && (x0 < x[i+1]);
        bool cond2 = (x[i+1] <= x0) && (x0 < x[i]);
        //容易错的地方:计算斜率时一定要判断它存不存在,否则会re 
        if((cond1 || cond2) && x[i+1]-x[i] == 0)
        {
            if(yy0 <= y[i] && yy0 >= y[i+1] || yy0 >= y[i] && yy0 <= y[i+1])
            {
                return true;
            }else{
                return false;
            }
        }else{
            double slope = (y[i+1]-y[i])/(x[i+1]-x[i]);
            bool above = (fabs(yy0-slope*(x0-x[i])+y[i])< 1e-7);
            bool e = (yy0 == slope*(x0-x[i])+y[i]);
            if((cond1 || cond2) && e) return true;
            if((cond1 || cond2) && above) crossings++;    
        }
    }
    return (crossings % 2 != 0);
} 

int main()
{
    while(~scanf("%lf%lf%d%d",&x0,&yy0,&n,&m))
    {
        int tag =-1;
        for(int i = 1;i <= n;i++)
        {
            for(int j = 0;j < m;j++)
            {
                scanf("%lf%lf",&x[j],&y[j]);
            }
            x[m] = x[0];y[m] = y[0];
            if(tag == -1)
            {
                if(contains(x0,yy0)) tag = i;    
            }
        }
        printf("%d\n",tag);
    }
}

 

posted @ 2017-11-24 21:16  INER  阅读(840)  评论(0编辑  收藏  举报