Hi,
Yo can get the picked point from the PromptEntityResult, then compute the point on the polyline (GetClosestPointTo), the get the polyline parameter at this point.
The parameter of a polyline is a double value, its integer part is the index of the previous vertex (0 for the 1st segment, 1 for the 2nd, ...), the decimal part is the ratio of the segment length (e.g. .25 at the quarter of the segment, .5 at the middle, ...).
With the indices of the vertices enclosing the picked point, you can get the coordinates of these vertices with GetPointAtParameter.
[CommandMethod("TEST")]
public static void Test()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var peo = new PromptEntityOptions("\nSelect Polyline: ");
peo.SetRejectMessage("\nNot a polyline, try again.");
peo.AddAllowedClass(typeof(Polyline), true);
var per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
var plineId = per.ObjectId;
var pickedPt = per.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem);
using (var tr = db.TransactionManager.StartTransaction())
{
var pline = (Polyline)tr.GetObject(plineId, OpenMode.ForRead);
var pointOnPline = pline.GetClosestPointTo(pickedPt, false);
double paramAtPoint = pline.GetParameterAtPoint(pointOnPline);
int segmentStartParam = (int)paramAtPoint;
int segmentEndParam = segmentStartParam + 1;
var segmentStartPoint = pline.GetPointAtParameter(segmentStartParam);
var segmentEndPoint = pline.GetPointAtParameter(segmentEndParam);
double radius = segmentStartPoint.DistanceTo(segmentEndPoint) / 10.0;
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
var circle = new Circle(segmentStartPoint, Vector3d.ZAxis, radius);
curSpace.AppendEntity(circle);
tr.AddNewlyCreatedDBObject(circle, true);
circle = new Circle(segmentEndPoint, Vector3d.ZAxis, radius);
curSpace.AppendEntity(circle);
tr.AddNewlyCreatedDBObject(circle, true);
tr.Commit();
}
}