判断一个点是否在多边形内部

判断一个点P是否在多边形内部,有下面一个简单有效的算法:
注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。
所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。
还有一些特殊情况要考虑。
假如考虑边(P1,P2)
1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况
2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。
3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。
4)再判断相交之前,先判断P是否在边(P1,P2)的上面,如果在,则直接得出结论:P再多边形内部。

相关题目可以看下:http://acm.zju.edu.cn/show_problem.php?pid=1081

my code:
#include <iostream>
using namespace std;
#define eps 1.0e-5

inline 
double max(double a,double b) return a>b?a:b; }
inline 
double min(double a,double b) return a<b?a:b; }
inline 
double dabs(double a) return a<0?-a:a; }
struct Point {
    
double x,y;
}
;

Point poly[
110];
int n,m;

bool online(const Point& p1,const Point& p2,const Point& p3) {
    
if(p2.x>=min(p1.x,p3.x)&&p2.x<=max(p1.x,p3.x)
        
&&p2.y>=min(p1.y,p3.y)&&p2.y<=max(p1.y,p3.y)) {
        
if(dabs((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))<=eps)
            
return true;
    }

    
return false;
}


bool insidepolygon(Point p) {
    
int counter=0;
    
double xinters;
    Point p1,p2;

    p1
=poly[0];
    
for(int i=1;i<=n;i++{
        p2
=poly[i%n];
        
if(online(p1,p,p2)) return true;
        
if(p.y>min(p1.y,p2.y)) {
            
if(p.y<=max(p1.y,p2.y)) {
                
if(p.x<=max(p1.x,p2.x)) {
                    
if(p1.y!=p2.y) {
                        xinters
=(p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
                        
if(p1.x==p2.x||p.x<=xinters) counter++;
                    }

                }

            }

        }

        p1
=p2;
    }

    
if(counter%2==0)
        
return false;
    
return true;
}


int main() {
    
int t=0;
    Point p;
    
while(cin>>n) {
        
if(n==0break;
        
if(t++>0) cout<<endl;
        cout
<<"Problem "<<t<<":"<<endl;
        cin
>>m;
        
for(int i=0;i<n;i++)
            cin
>>poly[i].x>>poly[i].y;
        
for(int i=0;i<m;i++{
            cin
>>p.x>>p.y;
            
if(insidepolygon(p)) 
                cout
<<"Within"<<endl;
            
else
                cout
<<"Outside"<<endl;
        }

    }

    
return 0;
}


posted on 2007-07-27 18:36  woodfish  阅读(1419)  评论(0编辑  收藏  举报

导航