给定一个由凸多边形顶点坐标构成的点集(Polygon),判断一个点(Target)是否在这个凸多边形内。
首先需要对点集进行排序,确保点的顺序为顺时针方向或逆时针方向,暂且忽略这一步。
假设点集已经按顺时针排好,那么从某点出发,沿着顺时针方向前进,如果目标点始终处于前进方向的右侧(逆时针则位于左侧),那就说明该点在多边形内。使用向量叉乘法判断目标点位于左侧还是右侧。
如图,绿色箭头为当前点指向下一个点的向量vector1和指向目标点的向量vector2,二者叉乘结果的正负可以表示二者之间夹角关系:
若叉乘结果小于0 说明点位于向量右侧,反之则位于左侧。因此遍历点集,判断叉乘结果是否都大于0或是否都小于0 就能知道点是否位于向量的同一侧。
代码实现:
public struct Point
{
public double X;
public double Y;
}
public static double CrossProduct (Point Vector1, Point Vector2)
{
return Vector1.X * Vector2.Y - Vector2.X * Vector1.Y;
}
public static bool IsPointInRegion (Point Target, List<Point> Polygon)
{
double currValue= 0;
double lastValue = 0;
int n = Polygon.Count;
for (int i = 0; i < n; i++)
{
var currPoint = Polygon[i];
var nextPoint = Polygon[(i + 1) % n];
var Vector1 = new Point(Target.X - currPoint.X, Target.Y - currPoint.Y);
var Vector2 = new Point(nextPoint.X - currPoint.X, nextPoint.Y - currPoint.Y);
currValue = crossProduct(vector1, vector2);
if (currValue * lastValue < 0 && i > 0) return false;
lastValue = currValue;
}
return true;
}