如何确定点是否在具有弧的二维多边形内
How to determine if a Point is inside of a 2D Polygon that has Arcs
我一直在使用以下参考来尝试确定点是否在具有弧的二维多边形内部:
Is a point inside of 2D polygon, no curves
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
我一直在使用以下参考来尝试确定点是否在具有弧的二维多边形内部:
Is a point inside of 2D polygon, no curves
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