测试结果:

主要思路:选择一段多段线,使用封装的jig类进行实时拖动,其原理就是在拖动的时候,确定被拖动的边,我是选择离输入第一个点最近的边作为拖动边,有了这条边,就能确定需要实时更改的点了,然后当鼠标拖动的时候,限制拖动方向只能是X轴或者Y轴变换,详细我在代码里都写了注释的。不足之处就是选择之后,我是把原来的对象复制一份,在删除了原对象,不知道是不是这个原因,Polyline会在选择之后消失,再次点击又出现了。我试了如果直接以写的方式操作原对像,cad会报错,说NotOpenForWrite,我也不知道这是什么原因。下面贴出所有的代码。

Jig操作类:

public class MyJig : DrawJig
{ public Point3d Point = Point3d.Origin; Func<JigPrompts, SamplerStatus> InputFunc; public List<Entity> JigEnts = new List<Entity>();
Action<MyJig> JigUpdateAction; public MyJig()
{
JigEnts.Clear();
InputFunc = null;
} public void SetJigUpdate(Action<MyJig> action)
{
JigUpdateAction = action;
} public void PromptInput(JigPromptPointOptions pointOpts, string msg)
{
InputFunc = (prmpts) =>
{ pointOpts.Message = msg; var res = prmpts.AcquirePoint(pointOpts);
//Point就是我们要更新实体数据的点
if (res.Value == Point)
{
return SamplerStatus.NoChange;
}
else if (res.Value != Point)
{
Point = res.Value;
return SamplerStatus.OK;
}
else
{
return SamplerStatus.Cancel;
} }; } protected override SamplerStatus Sampler(JigPrompts prompts)
{
if (InputFunc == null)
{
return SamplerStatus.NoChange;
} return InputFunc.Invoke(prompts);
} protected override bool WorldDraw(WorldDraw draw)
{
if (JigEnts.Count > )
{
//这是个委托,主要实现你要如何去更新你的实体
JigUpdateAction(this);
foreach (var ent in JigEnts)
{
ent.WorldDraw(draw);
}
}
return true;
} public PromptStatus Drag()
{
return Application.DocumentManager.MdiActiveDocument.Editor
.Drag(this).Status;
}
}

这个类在我的另一篇jig操作里做了点介绍的:

https://www.cnblogs.com/HelloQLQ/p/12000879.html
命令类:

public class MyDrag
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Database db = Application.DocumentManager.MdiActiveDocument.Database;
Polyline pl = null;
bool IsDrag = false;
[CommandMethod("MyDrag")]
public void DragIt()
{
IsDrag = false;
PromptEntityOptions entOpts = new PromptEntityOptions("请选择Polyline"); entOpts.SetRejectMessage("请选择多段线");
entOpts.AddAllowedClass(typeof(Polyline), true); var pEntRes = ed.GetEntity(entOpts); if (pEntRes.Status != PromptStatus.OK)
return; Polyline plCo = null;
using (var trans = db.TransactionManager.StartTransaction())
{ pl = trans.GetObject(pEntRes.ObjectId, OpenMode.ForWrite) as Polyline; //这里如果不复制,直接操作pl,虽然是以写的方式打开的实体,但是会报错说NotOpenForWrite
plCo = pl.Clone() as Polyline; pl.Erase(); trans.Commit(); } List<LineSegment2d> listL2d = new List<LineSegment2d>();
for (int i = ; i < pl.NumberOfVertices - ; i++)
{
listL2d.Add(pl.GetLineSegment2dAt(i));
} var pointRes = ed.GetPoint(new PromptPointOptions("请输入一地个点:\n")); if (pointRes.Status != PromptStatus.OK) return; Vector2d v2d = new Vector2d(, ); JigPromptPointOptions jigOpts = new JigPromptPointOptions(); MyJig myJig = new MyJig(); myJig.PromptInput(jigOpts, "拖动鼠标");
myJig.JigEnts.Add(plCo); int dir = -; myJig.SetJigUpdate((jig) =>
{
if (jig.JigEnts == null || jig.JigEnts.Count == )
{
return;
} Polyline p = jig.JigEnts[] as Polyline; var pt1 = pointRes.Value; var pt2 = jig.Point; var vec = pt2 - pt1; /*获取鼠标拖动方向,主要思路
*当拖动的距离拖动前按下的那个点的
* 距离>1的时候,计算是X轴方向还是Y轴方向
* 因为第一次判断,如果距离过下方向不准确。
* 并且这个方向一确定,就不在更改。
*/
if (!IsDrag)
{
if (vec.Length > )
{
IsDrag = true; if (Math.Abs(vec.X) > Math.Abs(vec.Y))
{
dir = ; }
else
{
dir = ;
}
} }
//向右或者向左
if (dir == )
{ v2d = new Vector2d(vec.X, ); }
else//向上或者向下
{
v2d = new Vector2d(, vec.Y); } /*
* 确定要拖动的边是选择距离鼠标按下的那个点最近的边
*/
double minLength = double.MaxValue; int index = -; foreach (var i in Enumerable.Range(, listL2d.Count))
{
var l = listL2d[i];
double dis = l.GetDistanceTo(new Point2d(pointRes.Value.X, pointRes.Value.Y)); if (dis < minLength)
{ minLength = dis;
index = i;
} } var l2d = listL2d[index]; Matrix2d mtx2d = Matrix2d.Displacement(v2d); var ptGet1 = l2d.StartPoint;
var ptGet2 = l2d.EndPoint; //实时得到变化的点
var ptStart = ptGet1.TransformBy(mtx2d);
var ptEnd = ptGet2.TransformBy(mtx2d); var vecGet = ptGet2 - ptGet1; //判断鼠标移动的方向和被拖动的边是否是在大致的同一方向
//如果不是,就允许拖动
if (dir == && (Math.Abs(vecGet.X) < Math.Abs(vecGet.Y)) ||
dir == && (Math.Abs(vecGet.X) > Math.Abs(vecGet.Y)))
{
p.SetPointAt(index, ptStart);
p.SetPointAt(index + , ptEnd); //如果polyline是封闭的,要判断被拖动的点是否是闭合位置上的点,
//如果是,要一致更改起点和封闭点
if (p.Closed)
{
if (index == )
{
p.SetPointAt(p.NumberOfVertices - , ptStart);
}
if (index + == )
{
p.SetPointAt(p.NumberOfVertices - , ptEnd);
}
if (index == p.NumberOfVertices - )
{
p.SetPointAt(, ptStart);
}
if (index + == p.NumberOfVertices - )
{
p.SetPointAt(, ptEnd);
}
}
}
}); if (myJig.Drag() != PromptStatus.OK)
{ return;
} IsDrag = false; //加入到模型空间
myJig.JigEnts.ToSpace();
myJig.JigEnts.ForEach(a => a.Dispose());
} }

最新文章

  1. [译]:Xamarin.Android开发入门——Hello,Android Multiscreen快速上手
  2. NSMutableAttributedString常用代码
  3. openGL漫游功能简单实现
  4. 杀死mapreduce
  5. vs.net git版本仓库使用 之解决冲突方法 原创
  6. PHP图像处理之在原图像处理
  7. NYOJ-86 找球号(一)AC 分类: NYOJ 2014-02-02 10:45 160人阅读 评论(0) 收藏
  8. 用DateTime.ToString(string format)输出不同格式的日期
  9. mfc开发问题_v1
  10. lightoj 1030 概率dp
  11. (转载)linux那点事儿(中)
  12. JUnit4 与 JMock 之双剑合璧
  13. P3092 [USACO13NOV]没有找零No Change
  14. 【LeetCode】无重复字符串最长子串
  15. linux每日命令(33):diff命令
  16. 滚动条事件,当页面滚动到距顶部一定高度时某DIV自动隐藏和显示
  17. Spring编程式和声明式事务实例讲解
  18. 字符串 - KMP模式匹配
  19. MacBook鼠标指针乱窜/不受控制问题的解决方法
  20. unity, AnimatorCullingMode的一个bug

热门文章

  1. MySQL5.7默认打开ONLY_FULL_GROUP_BY模式问题与解决方案
  2. 2019-8-31-dotnet-通过-WMI-获取系统补丁
  3. mysql数据库之mysql下载与设置
  4. 史上最全的MYSQL备份方法
  5. CODE FESTIVAL 2017 qual A D Four Coloring(补题)
  6. hdu 2126 Buy the souvenirs(记录总方案数的01背包)
  7. [WC2013]平面图——平面图点定位
  8. [转]什么是CNN、RNN、LSTM
  9. word 筛选过的网页,网页,单个文件网页
  10. [学习笔记]k短路