Author Topic: Polyline3d GetClosest​PointTo, GetObjectS​napPoints  (Read 1079 times)

0 Members and 1 Guest are viewing this topic.


  • Guest
Polyline3d GetClosest​PointTo, GetObjectS​napPoints
« on: December 17, 2012, 11:48:14 AM »
I am trying to get a point on (or possibly extended from the end of) a 3D polyline closest to a specified point. In the attached drawing, there is a 3D Polyline, and two nodes.

In AutoCAD, if I draw a line from the node at 1239.817,994.9588,91.7498 perpendicular to the polyline, it snaps to (1239.8705, 999.9583, 91.6499) - which is the desired result.

 The code below shows 3 methods of trying to obtain this result, but without success. The output of this is:

 pickedPt: (1239.8717322503,994.958757180007,91.7498303566326​)
 testPt1: (1234.21981294827,999.958333333333,91.721057443587​6)
 testPt2: (1239.87317003466,999.958333333333,92.293015903588​4)
 testPt3: (1234.21981294827,999.958333333333,91.721057443587​6)
 Snap Point Count: 503

 So, the issue with Method 1 is that it does not extend the polyline. Which led me to Method 2.

 The issue with Method 2 is that it is not using the end of the polyline to determine the direction it should extend.

 The issue with Method 3 is that it doesn't extend the polyline (the result is the same as Method 1). Actually, after looking at the contents of the Point3dCollection more closely, it appears that the vertices of the Polyline3d are all that is returned - nothing that is actually meaningful given the ObjectSnapModes.ModePerpendicular parameter.

The code below assumes that the UCS is World - a poor assumption, but I'm just trying to get something that works before worrying about that.

Any suggestions?

Code: [Select]
public static void ClosestPl3dTest()
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor acEd = acDoc.Editor;

            PromptEntityResult per  = acEd.GetEntity("Select Polyline3d");
            if (per.Status == PromptStatus.OK)
                Polyline3d pl = null;
                using (Transaction acTrans = acDoc.TransactionManager.StartTransaction())
                    DBObject obj = acTrans.GetObject(per.ObjectId, OpenMode.ForRead);
                    if (obj is Polyline3d)
                        pl = (Polyline3d)obj;
                if (pl != null)
                    PromptPointResult ppr = acEd.GetPoint("Select point");
                    if (ppr.Status == PromptStatus.OK)
                        Point3d pickedPt = ppr.Value;

                        // Method 1
                        Point3d testPt1 = pl.GetClosestPointTo(pickedPt, false);

                        // Method 2
                        Point3d testPt2 = pl.GetClosestPointTo(pickedPt, true);
                        // Method 3
                        Point3dCollection ptColl = new Point3dCollection();
                        IntegerCollection intColl = new IntegerCollection();
                        Matrix3d identity = Matrix3d.Identity;
                        pl.GetObjectSnapPoints(ObjectSnapModes.ModePerpend​icular, 1, pickedPt, pickedPt, identity, ptColl, intColl);
                        Point3d[] array = new Point3d[ptColl.Count];
                        ptColl.CopyTo(array, 0);

                        // return the closest result
                        Point3d testPt3 = array.OrderBy(pt => pt.DistanceTo(pickedPt)).First();

                        acEd.WriteMessage("\npickedPt: " + pickedPt.ToString() + "\n");
                        acEd.WriteMessage("testPt1: " + testPt1.ToString() + "\n");
                        acEd.WriteMessage("testPt2: " + testPt2.ToString() + "\n");
                        acEd.WriteMessage("testPt3: " + testPt3.ToString() + "\n");
                        acEd.WriteMessage("Snap Point Count: " + ptColl.Count + "\n");