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
{
public class Commands
{
[CommandMethod("POP")]
public void PointOnPolyline()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo =
new PromptEntityOptions("\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) as Polyline;
if (polyline != null)
{
bool isOn = IsPointOnPolyline(polyline, ppr.Value);
ed.WriteMessage(
"\nSelected point is {0}on the polyline.",
isOn ? "" : "not "
);
}
tr.Commit();
}
}
private bool 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);
else if (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.
Update
An improved approach to this has been shown in this post.