I have been using the following references to try 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 compound polygon (C#)
Is a point inside a curve (Theory)
My approach uses Ray Casting to determine if a point is within the polygon boundary. This is my code that attempts to string the references together (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;
}
Note that some of the calls I am making (i.e. .GetPoint3dAt()) are from the AutoCAD .NET API. This approach works fine for any polygon that has no arcs, but when an arc is introduced, and the point lies within the bounds of the polygon perimeter, a false negative is produced.
Here is an example of the polygons I am testing:
Any help would be greatly appreciated, thank you.
I asked this question in the AutoDesk .NET Forum and recieved this solution: The Answer