private double _maxLength = 35.0;
[CommandMethod("RIA", CommandFlags.Modal)]
public void Ria()
{
Document doc = AcAp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptDistanceOptions pdo =
new PromptDistanceOptions
("\nSpecify maximum length: "); pdo.AllowNegative = false;
pdo.AllowNone = true;
pdo.AllowZero = false;
pdo.DefaultValue = _maxLength;
pdo.UseDefaultValue = true;
PromptDoubleResult pdr = ed.GetDistance(pdo);
if (pdr.Status != PromptStatus.OK)
return;
_maxLength = pdr.Value;
PromptPointOptions ppo
= new PromptPointOptions
("\nSpecify start point: "); PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
Matrix3d ucsMat = ed.CurrentUserCoordinateSystem;
CoordinateSystem3d ucs = ucsMat.CoordinateSystem3d;
Point3d startPt = ppr.Value.TransformBy(ucsMat);
Plane plane
= new Plane
(Point3d
.Origin, ucs
.Zaxis); using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
Polyline pline
= new Polyline
(); pline.Normal = ucs.Zaxis;
pline.Elevation = Point3d.Origin.TransformBy(ucsMat).Z;
pline.AddVertexAt(0, startPt.Convert2d(plane), 0.0, 0.0, 0.0);
pline.AddVertexAt(1, startPt.Convert2d(plane), 0.0, 0.0, 0.0);
pline.ColorIndex = 8;
space.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
Circle circle
= new Circle
(ppr
.Value.TransformBy(ucsMat
), ucs
.Zaxis, _maxLength
); circle.ColorIndex = 8;
space.AppendEntity(circle);
tr.AddNewlyCreatedDBObject(circle, true);
db.TransactionManager.QueueForGraphicsFlush();
while (true)
{
RiaJig jig
= new RiaJig
(pline, circle, _maxLength
); PromptResult pr = ed.Drag(jig);
if (pr.Status == PromptStatus.Cancel)
{
pline.Erase();
circle.Erase();
break;
}
if (pr.Status != PromptStatus.OK)
{
pline.RemoveVertexAt(pline.NumberOfVertices - 1);
circle.Erase();
pline.ColorIndex = 256;
break;
}
if (_maxLength - pline.Length <= 1e-12)
{
circle.Erase();
pline.ColorIndex = 256;
break;
}
pline.AddVertexAt(pline.NumberOfVertices, pline.EndPoint.Convert2d(plane), 0.0, 0.0, 0.0);
}
tr.Commit();
}
}
class RiaJig : DrawJig
{
private Circle circle;
private Polyline pline;
private double maxRad;
Point3d dragPt;
Plane plane;
public RiaJig(Polyline pline, Circle circle, double maxRad)
{
this.pline = pline;
this.circle = circle;
this.maxRad = maxRad;
dragPt = circle.Center;
plane
= new Plane
(Point3d
.Origin, pline
.Normal); }
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
Autodesk.AutoCAD.GraphicsInterface.WorldGeometry geo = draw.Geometry;
if (geo != null)
{
geo.PushModelTransform(Matrix3d.Identity);
geo.Draw(circle);
geo.Draw(pline);
geo.PopModelTransform();
}
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions opts =
new JigPromptPointOptions
("\nSpecify next point: "); opts.UserInputControls = UserInputControls.NullResponseAccepted;
PromptPointResult ppr = prompts.AcquirePoint(opts);
if (ppr.Value.DistanceTo(dragPt) < Tolerance.Global.EqualPoint)
return SamplerStatus.NoChange;
dragPt = ppr.Value;
Update();
return SamplerStatus.OK;
}
private void Update()
{
circle.Center = dragPt;
circle.Radius = Math.Max(maxRad - pline.Length, 1e-12);
int nov = pline.NumberOfVertices;
Point2d pt = dragPt.Convert2d(plane);
pline.SetPointAt(nov - 1, pt);
if (pline.Length > maxRad)
{
Point2d lastPt = pline.GetPoint2dAt(nov - 2);
Vector2d dir = (pt - lastPt).GetNormal();
pline.SetPointAt(nov - 1, lastPt + dir * (maxRad - pline.GetDistanceAtParameter(nov - 2)));
}
}
}