December 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      










« Colours to use for contextual ribbon tabs in AutoCAD | Main | Testing whether a point is on any AutoCAD curve using .NET »

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

{

  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.

blog comments powered by Disqus

Feed/Share

10 Random Posts