Polyline3d GetClosestPointTo, GetObjectSnapPoints
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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.7210574435876)
testPt2: (1239.87317003466,999.958333333333,92.2930159035884)
testPt3: (1234.21981294827,999.958333333333,91.7210574435876)
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).
Any suggestions?
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;
}
acTrans.Commit();
}
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.ModePerpendicular, 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");
}
}
}
}