Я использовал следующие ссылки, чтобы попытаться определить, находится ли точка внутри 2D-полигона с дугами:
Это точка внутри двумерного многоугольника, без кривых
Это точка внутри составного многоугольника (C#)
Это точка внутри кривой (Теория)
Мой подход использует Ray Casting, чтобы определить, находится ли точка в пределах границы полигона. Это мой код, который пытается объединить ссылки (С#):
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. Этот подход прекрасно работает для любого многоугольника, не имеющего дуг, но когда дуга введена и точка находится в пределах границ периметра многоугольника, возникает ложный отрицательный результат.
Вот пример полигонов, которые я тестирую:
Любая помощь будет принята с благодарностью, спасибо.