问题描述
我一直在使用以下参考资料来尝试确定一个点是否在具有弧线的 2D 多边形内:
Is a point inside of 2D polygon,no curves
Is a point inside a compound polygon (C#)
Is a point inside a curve (Theory)
我的方法使用光线投射来确定一个点是否在多边形边界内。这是我尝试将引用串在一起的代码(C#):
public static bool IsInsideBoundary(polyline pline,Point3d pnt,Document currentDoc)
{
try
{
if (pline.Closed == true)
{
Tools.Log("polyline is Closed");
// Check if point is on the line -> WORKS
if (IsPointOnCurve(pline,pnt))
{
Log("Point is on the Boundary line");
return true;
}
else
{
int numOfVerts = pline.NumberOfVertices;
// Get bounding Box of boundary
double minX = pline.GetPoint3dAt(0).X;
double maxX = pline.GetPoint3dAt(0).X;
double minY = pline.GetPoint3dAt(0).Y;
double maxY = pline.GetPoint3dAt(0).Y;
for (int i = 1; i < numOfVerts; i++)
{
Point3d q = pline.GetPoint3dAt(i);
minX = Math.Min(q.X,minX);
maxX = Math.Max(q.X,maxX);
minY = Math.Min(q.Y,minY);
maxY = Math.Max(q.Y,minY);
}
// Check if the given point outside of the bounding Box
if (pnt.X < minX || pnt.X > maxX || pnt.Y < minY || pnt.Y > maxY)
{
return false;
}
Log("Bounding Box check passed...");
bool inside = false;
for (int i = 0,j = numOfVerts - 1; i < numOfVerts; j = i++)
{
double a1 = pline.GetPoint3dAt(i).X,a2 = pline.GetPoint3dAt(i).Y;
double b1 = pnt.X,b2 = pnt.Y;
double c1 = pline.GetPoint3dAt(j).X,c2 = pline.GetPoint3dAt(j).Y;
// Use the Jordan Curve Theorem
double d1 = (c1 - a1) * (b2 - a2) / (c2 - a2) + a1;
// Split arc into monotone parts and check bounds
if ((a2 > b2) != (c2 > b2) && b1 < d1)
{
inside = !inside;
}
}
Log("Point is within the boundary");
return inside;
}
}
else
{
Log("Boundary is not closed.");
}
}
catch (System.Exception e)
{
Log("InsideBoundary() Failed. Exception: " + e.Message,true);
}
return false;
}
请注意,我所做的一些调用(即 .GetPoint3dAt())来自 AutoCAD .NET API。这种方法适用于任何没有弧的多边形,但是当引入弧并且该点位于多边形周长的边界内时,就会产生假阴性。
如有任何帮助,将不胜感激,谢谢。
解决方法
我在 AutoDesk .NET 论坛中提出了这个问题并收到了这个解决方案: The Answer