判断一点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;