射线法
射线法是用被测点向任意方向(通常为了好算,使其射向右侧)做一条射线,判断射线与多边形的交点。如果交点的数量为奇数,则被测点在多边形内;如果交点的数量为偶数,则被测点在多边形以外。
使用实例
下面看下集中情况:
a点在多边形内
a点在多边形外
代码说明
1.点与多边形顶点重合
// 点与多边形的顶点重合
if (((start.x == ref.x) && (start.y == ref.y)) || ((end.x == ref.x) && (end.y == ref.y)))
{
return true;
}
2.判断线段两端点是否在射线两侧
if (((ref.y >= start.y)&&(ref.y < end.y)) || ((ref.y >= end.y)&&(ref.y < start.y)))
3.判断点是在线段的右边还是左边
现根据两点式直线方程求出a点的x值
两点式方程公式:(y-y1)/(y2-y1)=(x-x1)/(x2-x1)。
// 线段上与射线 Y 坐标相同的点的 X 坐标
x = start.x + (ref.y - start.y) * (end.x - start.x) / (end.y - start.y);
x值为a点出的x值,判断点ref是在线段的左边还是右边
// 射线穿过多边形的边界
if (x > ref.x)
{
++count;
}
完成代码
// 射线法判断点在多边形的内部或外部
bool PtInPolygon(CPoint ref, TVA_Polygon poly)
{
int i, j, n;
n = poly.numPoints;
long int x;
int count = 0;
CPoint start, end;
if (0 == n)
{
return false;
}
for (i = 0, j = n-1; i < n; j = i++)
{
start.x = poly.points[i].x;
start.y = poly.points[i].y;
end.x = poly.points[j].x;
end.y = poly.points[j].y;
// 点与多边形的顶点重合
if (((start.x == ref.x) && (start.y == ref.y)) || ((end.x == ref.x) && (end.y == ref.y)))
{
return true;
}
// 判断线段两端点是否在射线两侧
if (((ref.y >= start.y)&&(ref.y < end.y)) || ((ref.y >= end.y)&&(ref.y < start.y)))
{
// 线段上与射线 Y 坐标相同的点的 X 坐标
x = start.x + (ref.y - start.y) * (end.x - start.x) / (end.y - start.y);
// 点在多边形的边上
if (ref.x == x)
{
return true; // onside
}
// 射线穿过多边形的边界
if (x > ref.x)
{
++count;
}
}
}
// 射线穿过多边形边界的次数为奇数时点在多边形内
return (count%2) ? true/*inside*/ : false/*outside*/;
}