判定一点是否在多边形内

判断一点P是否在多边形内部的算法一般有两种:射线交点法(ray crossing number method),绕数法(windig number method)


射线交点法(ray crossing number method)
   以从此点为原点引一射线,然后统计此射线与多边形各边交点的数量。如果与射线相交的边的数量是偶数,则此点落在多变形外,否则落在多边形内。


绕数法(windig number method)
   统计多边形绕点P的次数(绕数)。如果这个绕数是0,则点在多边形内,否则点在多边形外。

[1]给出了射线交点法的C++语言的一个实现,根据[1]给出的代码,将点坐标数据类型由int转换为double

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>

static double ESP = 0.0001;
double max( double a, double b )
{
	  return (a > b)? a:b;
} 
double min( double a, double b )
{
	  return (a < b)? a:b;
} 

class Grid
{
public:
	Grid()
	{
		_X = 0.0;
		_Y = 0.0;
		_Z = 0.0;
	}
	Grid( double X, double Y, double Z )
	{
		_X = X;
		_Y = Y;
		_Z = Z;
         }
	;
	virtual ~Grid()
	{
	}
	;
public:
	bool isSame(Grid theGrid )
	{
		bool result = false;
		if (fabs(_X - theGrid._X) > ESP)
		{
			return result;
		}
		if (fabs(_Y - theGrid._Y) > ESP)
		{
			return result;
		}
		if (fabs(_Z - theGrid._Z) > ESP)
		{
			return result;
		}
		result = true;
		return result;
	}
       void show()
      {
	   printf("[%f, %f, %f]\n", _X, _Y, _Z);
      }
public:
	double _X;
	double _Y;
	double _Z;
};

// http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
// Define Infinite (Using INT_MAX caused overflow problems)
#define INF 10000
 
double max( double a, double b )
{
	  return (a > b)? a:b;
} 
double min( double a, double b )
{
	  return (a < b)? a:b;
}  
//struct Point
//{
//    int x;
//    int y;
//};
 
// http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(Grid p, Grid q, Grid r)
{
    if (q._X <= max(p._X, r._X) && q._X >= min(p._X, r._X) &&
            q._Y <= max(p._Y, r._Y) && q._Y >= min(p._Y, r._Y))
        return true;
    return false;
}
 
// http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Grid p, Grid q, Grid r)
{
    int val = (q._Y - p._Y) * (r._X - q._X) -
              (q._X - p._X) * (r._Y - q._Y);
 
    if (val == 0) return 0;  // colinear
    return (val > 0)? 1: 2; // clock or counterclock wise
}
 
// http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
// The function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Grid p1, Grid q1, Grid p2, Grid q2)
{
    // Find the four orientations needed for general and
    // special cases
    int o1 = orientation(p1, q1, p2);
    int o2 = orientation(p1, q1, q2);
    int o3 = orientation(p2, q2, p1);
    int o4 = orientation(p2, q2, q1);
 
    // General case
    if (o1 != o2 && o3 != o4)
        return true;
 
    // Special Cases
    // p1, q1 and p2 are colinear and p2 lies on segment p1q1
    if (o1 == 0 && onSegment(p1, p2, q1)) return true;
 
    // p1, q1 and p2 are colinear and q2 lies on segment p1q1
    if (o2 == 0 && onSegment(p1, q2, q1)) return true;
 
    // p2, q2 and p1 are colinear and p1 lies on segment p2q2
    if (o3 == 0 && onSegment(p2, p1, q2)) return true;
 
     // p2, q2 and q1 are colinear and q1 lies on segment p2q2
    if (o4 == 0 && onSegment(p2, q1, q2)) return true;
 
    return false; // Doesn't fall in any of the above cases
}
 
// http://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
// Returns true if the point p lies inside the polygon[] with n vertices
bool isInside(std::vector<Grid> polygon,  Grid p)
{
    int n = polygon.size();
    // There must be at least 3 vertices in polygon[]
    if (n < 3)  return false;
 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值