A blog for developers programming with Autodesk platforms, particularly AutoCAD and Forge. With a special focus on AR/VR and IoT.

January 06, 2012

Testing whether a point is on an AutoCAD polyline using .NET

Occasionally I come across a topic that I’m sure I’ve addressed in a previous post, but for the life of me I can’t track it down. The code in a recent response by Balaji Ramamoorthy, from the DevTech India team, fits firmly into this category: it shows how to iterate through a polyline’s segments, testing whether a point is on the polyline.

I did some refactoring of Balaji’s code to extract it into a helper function (although not an extension method, which people who use them may prefer), but otherwise this C# code is basically his.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

namespace PolylineTesting

{

publicclassCommands

{

[CommandMethod("POP")]

publicvoid PointOnPolyline()

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

Editor ed = doc.Editor;

PromptEntityOptions peo =

newPromptEntityOptions("\nSelect a polyline");

peo.SetRejectMessage("Please select a polyline");

peo.AddAllowedClass(typeof(Polyline), true);

PromptEntityResult per = ed.GetEntity(peo);

if (per.Status != PromptStatus.OK)

return;

PromptPointResult ppr = ed.GetPoint("\nSelect a point");

if (ppr.Status != PromptStatus.OK)

return;

Transaction tr = db.TransactionManager.StartTransaction();

using (tr)

{

Polyline polyline =

tr.GetObject(per.ObjectId, OpenMode.ForRead) asPolyline;

if (polyline != null)

{

bool isOn = IsPointOnPolyline(polyline, ppr.Value);

ed.WriteMessage(

"\nSelected point is {0}on the polyline.",

isOn ? "" : "not "

);

}

tr.Commit();

}

}

privatebool IsPointOnPolyline(Polyline pl, Point3d pt)

{

bool isOn = false;

for (int i = 0; i < pl.NumberOfVertices; i++)

{

Curve3d seg = null;

SegmentType segType = pl.GetSegmentType(i);

if (segType == SegmentType.Arc)

seg = pl.GetArcSegmentAt(i);

elseif (segType == SegmentType.Line)

seg = pl.GetLineSegmentAt(i);

if (seg != null)

{

isOn = seg.IsOn(pt);

if (isOn)

break;

}

}

return isOn;

}

}

}

When you run the POP command and select a polyline and a point, you’ll see a message on the command-line indicating whether the latter is on the former.