可实现效果如下(对象捕捉F3需打开,否则效果不好):
public class CircleJig : EntityJig{public static void DraCJig(){PromptPointResult ppr = Z.ed.GetPoint("a");if (ppr.Value == null) return;Point3d pt = ppr.Value;CircleJig circle = new CircleJig(pt);Polyjig poly = new Polyjig(pt);for (; ; ){PromptResult resJig = Z.ed.Drag(circle);//拖动圆if (resJig.Status == PromptStatus.Cancel){return;}if (resJig.Status == PromptStatus.OK) //确定, 则将圆添加到数据库// if (resJigpl.Status == PromptStatus.OK){Z.db.AddEntityToModeSpace(circle.GetEntity());//画圆break;}return;}for (; ; )//画完圆继续jig线,不需要可注释{PromptResult resJigpl = Z.ed.Drag(poly);//拖动线if (resJigpl.Status == PromptStatus.Cancel)// 放弃, 则退出.{return;}if (resJigpl.Status == PromptStatus.OK) //确定, 则将线添加到数据库{Z.db.AddEntityToModeSpace(poly.Updata());//画多段线break;}return;}}// private Point3d jCenter; // 圆心private double jRadius; // 半径public CircleJig(Point3d center): base(new Circle()) // 继承父类Circle的属性{((Circle)Entity).Center = center; // Entity 转化为Cirecle 对象 复制center}// 用于更新图像对象 这里更新属性时无需使用事务处理protected override bool Update(){if (jRadius > 0){((Circle)Entity).Radius = jRadius;}return true;}// 这个函数的作用是当鼠标在屏幕上移动时 就会被调用 实现这个函数时 一般是用它改变图形的属性 我们在这个类定义的属性protected override SamplerStatus Sampler(JigPrompts prompts){// 声明拖拽类jig提示信息JigPromptPointOptions jppo = new JigPromptPointOptions("\n 请指定圆上的一个点");char space = (char)32;jppo.Keywords.Add("U");jppo.Keywords.Add(space.ToString());jppo.UserInputControls = UserInputControls.Accept3dCoordinates;jppo.Cursor = CursorType.RubberBand;jppo.BasePoint = ((Circle)Entity).Center;jppo.UseBasePoint = true;// 获取拖拽时鼠标的位置状态PromptPointResult ppr = prompts.AcquirePoint(jppo);jRadius = ppr.Value.GetDistanceBetweenTwoPoint(((Circle)Entity).Center);return SamplerStatus.NoChange; // 继续移动 循环检测}public Entity GetEntity(){return Entity;}}public class Polyjig : Autodesk.AutoCAD.EditorInput.DrawJig{public Point3d location;public Point3d basePoint;public Polyline polyine = new Polyline();public Plane plane = new Plane();public int index;public static void DrawPLJig(){PromptPointResult ppr = Z.ed.GetPoint("a");if (ppr.Value == null) return;Point3d pt = ppr.Value;Polyjig poly = new Polyjig(pt);for (; ; ){PromptResult resJigpl = Z.ed.Drag(poly);//拖动线 if (resJigpl.Status == PromptStatus.Cancel) // 放弃, 则退出.{return;}if (resJigpl.Status == PromptStatus.OK) //确定, 则将线添加到数据库{Z.db.AddEntityToModeSpace(poly.Updata());//画多段线break;}return;}}public Polyjig(Point3d basept){location = basept;basePoint = basept;polyine.AddVertexAt(0, basePoint.Convert2d(plane), 0, 0, 0);polyine.AddVertexAt(1, location.Convert2d(plane), 0, 0, 0);}protected override SamplerStatus Sampler(JigPrompts prompts){var opts = new JigPromptPointOptions("\n 输入下一个点");opts.UserInputControls = (UserInputControls.Accept3dCoordinates |UserInputControls.NoZeroResponseAccepted| UserInputControls.NoNegativeResponseAccepted);var res = prompts.AcquirePoint(opts);if (res.Value != location){location = res.Value;}else{return SamplerStatus.NoChange;}if (res.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}else{return SamplerStatus.OK;}}protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw){Updata();draw.Geometry.Draw(polyine);return true;}public Polyline Updata(){index = polyine.NumberOfVertices - 1;polyine.SetPointAt(index, location.Convert2d(plane));basePoint = location;return polyine;}}
其他形式:
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;namespace UseEntityJig
{class CircleJig : EntityJig{private Point3d m_CenterPt;public double m_Radius = 100.0;// 派生类的构造函数.public CircleJig(Vector3d normal): base(new Circle()){((Circle)Entity).Center = m_CenterPt;((Circle)Entity).Normal = normal;((Circle)Entity).Radius = m_Radius;}protected override bool Update(){((Circle)Entity).Center = m_CenterPt;((Circle)Entity).Radius = m_Radius;return true;}protected override SamplerStatus Sampler(JigPrompts prompts){// 定义一个点拖动交互类.JigPromptPointOptions optJig = new JigPromptPointOptions("\n请指定圆的圆心或用右键修改半径");optJig.Keywords.Add("100");optJig.Keywords.Add("200");optJig.Keywords.Add("300");optJig.UserInputControls = UserInputControls.Accept3dCoordinates;// 用AcquirePoint函数得到用户输入的点.PromptPointResult resJigDis = prompts.AcquirePoint(optJig);Point3d curPt = resJigDis.Value;if (resJigDis.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}if (resJigDis.Status == PromptStatus.Keyword){switch (resJigDis.StringResult){case "100":m_Radius = 100;return SamplerStatus.NoChange;case "200":m_Radius = 200;return SamplerStatus.NoChange;case "300":m_Radius = 300;return SamplerStatus.NoChange;}}if (m_CenterPt != curPt){// 保存当前点.m_CenterPt = curPt;return SamplerStatus.OK;}else{return SamplerStatus.NoChange;}}// GetEntity函数用于得到派生类的实体.public Entity GetEntity(){return Entity;}}
}
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;namespace UseEntityJig
{class EllipseJig : EntityJig{// 声明全局变量.private Point3d m_CenterPt, m_MajorPt;private Vector3d m_Normal, m_MajorAxis;private int m_PromptCounter;private double m_OtherAxisLength, m_RadiusRatio;private double m_StartAng, m_EndAng, m_ang1, m_ang2;// 派生类的构造函数.public EllipseJig(Point3d center, Vector3d vec): base(new Ellipse()){m_CenterPt = center;m_Normal = vec;}protected override bool Update(){if (m_PromptCounter == 0){// 第一次拖拽时,椭圆的半径比为1,屏幕上显示的是一个圆.m_RadiusRatio = 1;m_MajorAxis = m_MajorPt - m_CenterPt;m_StartAng = 0;m_EndAng = 2 * Math.PI;}else if (m_PromptCounter == 1){// 第二次拖拽时,修改了椭圆的半径比,屏幕上显示的是一个完整椭圆.m_RadiusRatio = m_OtherAxisLength / m_MajorAxis.Length;}else if (m_PromptCounter == 2){// 第三次拖拽时,修改了椭圆的起初角度,屏幕上显示的是一个终止角度为360度的椭圆弧.m_StartAng = m_ang1;}else if (m_PromptCounter == 3){// 第四次拖拽时,修改了椭圆的终止角度,屏幕上显示的是一个最终的椭圆弧.m_EndAng = m_ang2;}try{if (m_RadiusRatio < 1)// 更新椭圆的参数.((Ellipse)(Entity)).Set(m_CenterPt, m_Normal, m_MajorAxis, m_RadiusRatio, m_StartAng, m_EndAng);else{// 如另一条半轴长度超过椭圆弧长轴方向矢量的长度,则要重新定义椭圆弧长轴方向矢量的方向和长度.Vector3d mMajorAxis2 = m_MajorAxis.RotateBy(0.5 * Math.PI, Vector3d.ZAxis).DivideBy(1 / m_RadiusRatio);// 更新椭圆的参数.((Ellipse)(Entity)).Set(m_CenterPt, m_Normal, mMajorAxis2, 1 / m_RadiusRatio, m_StartAng, m_EndAng);}}catch{// 此处不需要处理.}return true;}protected override SamplerStatus Sampler(JigPrompts prompts){if (m_PromptCounter == 0){// 定义一个点拖动交互类.JigPromptPointOptions optJigPoint = new JigPromptPointOptions("\n请指定椭圆弧轴上一点");// 设置拖拽的光标类型.optJigPoint.Cursor = CursorType.RubberBand;// 设置拖动光标基点.optJigPoint.BasePoint = m_CenterPt;optJigPoint.UseBasePoint = true;// 用AcquirePoint函数得到用户输入的点.PromptPointResult resJigPoint = prompts.AcquirePoint(optJigPoint);Point3d curPt = resJigPoint.Value;if (curPt != m_MajorPt){// 保存当前点.m_MajorPt = curPt;}else{return SamplerStatus.NoChange;}if (resJigPoint.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}else{return SamplerStatus.OK;}}else if (m_PromptCounter == 1){// 定义一个距离拖动交互类.JigPromptDistanceOptions optJigDis = new JigPromptDistanceOptions("\n请指定另一条半轴的长度");// 设置对拖拽的约束:禁止输入零和负值.optJigDis.UserInputControls = UserInputControls.NoZeroResponseAccepted |UserInputControls.NoNegativeResponseAccepted;// 设置拖拽的光标类型.optJigDis.Cursor = CursorType.RubberBand;// 设置拖动光标基点.optJigDis.BasePoint = m_CenterPt;optJigDis.UseBasePoint = true;// 用AcquireDistance函数得到用户输入的距离值.PromptDoubleResult resJigDis = prompts.AcquireDistance(optJigDis);double radiusRatioTemp = resJigDis.Value;if (radiusRatioTemp != m_OtherAxisLength){// 保存当前距离值.m_OtherAxisLength = radiusRatioTemp;}else{return SamplerStatus.NoChange;}if (resJigDis.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}else{return SamplerStatus.OK;}}else if (m_PromptCounter == 2){// 设置椭圆弧0度基准角.double baseAng;Vector2d mMajorAxis2d = new Vector2d(m_MajorAxis.X, m_MajorAxis.Y);if (m_RadiusRatio < 1){baseAng = mMajorAxis2d.Angle;}else{baseAng = mMajorAxis2d.Angle + 0.5 * Math.PI;}// 设置系统变量“ANGBASE”.Application.SetSystemVariable("ANGBASE", baseAng);// 定义一个角度拖动交互类.JigPromptAngleOptions optJigAngle1 = new JigPromptAngleOptions("\n请指定椭圆弧的起始角度");// 设置拖拽的光标类型.optJigAngle1.Cursor = CursorType.RubberBand;// 设置拖动光标基点.optJigAngle1.BasePoint = m_CenterPt;optJigAngle1.UseBasePoint = true;// 用AcquireAngle函数得到用户输入的角度值.PromptDoubleResult resJigAngle1 = prompts.AcquireAngle(optJigAngle1);m_ang1 = resJigAngle1.Value;if (m_StartAng != m_ang1){// 保存当前角度值.m_StartAng = m_ang1;}else{return SamplerStatus.NoChange;}if (resJigAngle1.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}else{return SamplerStatus.OK;}}else if (m_PromptCounter == 3){// 定义一个角度拖动交互类.JigPromptAngleOptions optJigAngle2 = new JigPromptAngleOptions("\n请指定椭圆弧的终止角度");// 设置拖拽的光标类型.optJigAngle2.Cursor = CursorType.RubberBand;// 设置拖动光标基点.optJigAngle2.BasePoint = m_CenterPt;optJigAngle2.UseBasePoint = true;// 用AcquireAngle函数得到用户输入的角度值.PromptDoubleResult resJigAngle2 = prompts.AcquireAngle(optJigAngle2);m_ang2 = resJigAngle2.Value;if (m_EndAng != m_ang2){// 保存当前角度值.m_EndAng = m_ang2;}else{return SamplerStatus.NoChange;}if (resJigAngle2.Status == PromptStatus.Cancel){return SamplerStatus.Cancel;}else{return SamplerStatus.OK;}}else{return SamplerStatus.NoChange;}}// GetEntity函数用于得到派生类的实体.public Entity GetEntity(){return Entity;}// setPromptCounter过程用于控制不同的拖拽.public void setPromptCounter(int i){m_PromptCounter = i;}}
}
command
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;namespace UseEntityJig
{public class Command{[CommandMethod("jc")]public void JigCircleTest(){Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;Matrix3d mt = ed.CurrentUserCoordinateSystem;Vector3d normal = mt.CoordinateSystem3d.Zaxis;CircleJig circleJig = new CircleJig(normal);for (; ; ){// 拖动PromptResult resJig = ed.Drag(circleJig);// 放弃, 则退出.if (resJig.Status == PromptStatus.Cancel){return;}// 确定, 则将圆添加到数据库if (resJig.Status == PromptStatus.OK){AppendEntity(circleJig.GetEntity());break;}}}[CommandMethod("JigEllipse")]public void JigEllipseTest(){Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;Database db = Application.DocumentManager.MdiActiveDocument.Database;// 备份系统变量“ANGBASE”.object oldAngBase = Application.GetSystemVariable("ANGBASE");// 普通的点交互操作.PromptPointOptions optPoint = new PromptPointOptions("\n请指定椭圆弧的圆心:");PromptPointResult resPoint = ed.GetPoint(optPoint);if (resPoint.Status != PromptStatus.OK){return;}// 定义一个EntityJig派生类的实例.EllipseJig myJig = new EllipseJig(resPoint.Value, Vector3d.ZAxis);// 第一次拖拽.myJig.setPromptCounter(0);PromptResult resJig = ed.Drag(myJig);if (resJig.Status != PromptStatus.OK){return;}// 第二次拖拽.myJig.setPromptCounter(1);resJig = ed.Drag(myJig);if (resJig.Status != PromptStatus.OK){return;}// 第三次拖拽.myJig.setPromptCounter(2);resJig = ed.Drag(myJig);if (resJig.Status != PromptStatus.OK){return;}// 第四次拖拽.myJig.setPromptCounter(3);resJig = ed.Drag(myJig);if (resJig.Status != PromptStatus.OK){return;}AppendEntity(myJig.GetEntity());// 还原系统变量“ANGBASE”.Application.SetSystemVariable("ANGBASE", oldAngBase);}private ObjectId AppendEntity(Entity ent){ObjectId entId;Database db = HostApplicationServices.WorkingDatabase;using (Transaction trans = db.TransactionManager.StartTransaction()){BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId,OpenMode.ForRead);BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);entId = btr.AppendEntity(ent);trans.AddNewlyCreatedDBObject(ent, true);trans.Commit();}return entId;}}
}