How to determine if a point is inside a contour?

Last updated: Saturday, November 15, 2025

We often need to determine if a point is inside a contour. For example, when we have labeled zones, we need to establish the link between a closed polyline and the text inside it.

There are several ways to proceed, but for me the simplest and most reliable is to use AutoCAD's BRep API. BRep stands for Boundary REPresentation. It's a 3D API, but we can use it with 2D objects such as regions.

The first step is to create a region from the curves that form the contour. We can do this with the Region.CreateFromCurves method:

DBObjectCollection regions = Region.CreateFromCurves(new DBObjectCollection { curve })!;
using var region = (Region)regions[0]!;

Here, we assume we have a single curve (closed polyline, circle, or ellipse). We use the using keyword to ensure the region object will be destroyed at the end, since we only need it temporarily.

The second step is to create a BRep object, also with using:

using var brep = new Brep(region);

The third step is to test if the point is in the region with the GetPointContainment() method:

brep.GetPointContainment(point, out PointContainment _);

This is where it gets a bit complicated. As I mentioned earlier, the BRep API is a 3D API. GetPointContainment() is used to determine whether a point is inside a 3D object like a cube.

As shown here, we have a point A inside the cube and a point B outside.

Point in a cube

That's why the out PointContainment parameter is an enumeration that can be Inside or Outside. But there's also another possibility: the point can be on the shell that separates the inside of the cube from the outside. PointContainment will then have the value OnBoundary.

If we look at the signature of GetPointContainment(), we see that it returns a BrepEntity object:

public BrepEntity GetPointContainment(
    Point3d point,
    out Autodesk.AutoCAD.BoundaryRepresentation.PointContainment containment
);

The shell is actually composed of faces, edges, and vertices. So if the point is located inside a face, a Face object will be returned. If the point is on an edge or vertex, an Edge or Vertex object will be returned.

But in the case of our region, which is a 2D object, we don't have a solid, but a single planar face that doesn't delimit a volume. So GetPointContainment() will never return Inside.

Point in a region

If the point is in the region, OnBoundary will be returned in the containment parameter and a Face or Edge object will be returned. We won't get a Vertex in this case, even if we pass a point that corresponds to a vertex of one of the curves forming the contour.

If the point is outside the region, Outside will be returned in the containment parameter and null will be returned.

Here's the code for a small command to let you experiment:

[CommandMethod("PTINCONTOUR")]
public static void PointInContour()
{
    Document document = Application.DocumentManager!.MdiActiveDocument!;
    Editor editor = document.Editor!;
    PromptEntityResult entityResult = editor.GetEntity("\nSelect a closed curve:")!;
    if (entityResult.Status != PromptStatus.OK)
        return;
    PromptPointResult pointResult = editor.GetPoint("\nSelect a point:")!;
    if (pointResult.Status != PromptStatus.OK)
        return;
    using Transaction transaction = document.TransactionManager!.StartTransaction()!;
    var curve = (Curve)entityResult.ObjectId.GetObject(OpenMode.ForRead)!;
    DBObjectCollection regions = Region.CreateFromCurves(new DBObjectCollection { curve })!;
    using var region = (Region)regions[0]!;
    using var brep = new Brep(region);
    BrepEntity? entity = brep.GetPointContainment(pointResult.Value, out PointContainment containment);
    editor.WriteMessage($"\nContainment: {containment}, Entity: {entity}");
    transaction.Commit();
}

So if GetPointContainment returns null, the point is outside the region. If it returns a Face object, the point is inside the region. If it returns an Edge object, the point is on the boundary of the region.

You can therefore write an IsInside method that returns a PointContainment by passing a point and one or more curves that form the contour.

public static PointContainment IsInside(Point3d point, Curve[] curves)
{
    ArgumentNullException.ThrowIfNull(curves);

    var collection = new DBObjectCollection();
    foreach (Curve curve in curves)
        collection.Add(curve);
    DBObjectCollection regions;
    try
    {
        regions = Region.CreateFromCurves(collection)!;
    }
    catch (Autodesk.AutoCAD.Runtime.Exception exception) when (exception.ErrorStatus == ErrorStatus.InvalidInput)
    {
        throw new ArgumentException("The curves do not form a valid region.", nameof(curves), exception);
    }
    using var region = (Region)regions[0]!;
    using var brep = new Brep(region);
    using BrepEntity? entity = brep.GetPointContainment(point, out PointContainment _);
    return entity switch
    {
        null => PointContainment.Outside,
        Face => PointContainment.Inside,
        _ => PointContainment.OnBoundary
    };
}

Coup de pouce Besoin d'un développement AutoCAD ? Contactez-moi pour un devis gratuit.