编辑FreeShape的点

我有一些GUI让用户绘制costimized GraphicsPath。 我使用GraphicsPath AddLine函数创建了它。

现在,我想实现您在附加的Microsoft Word图像中看到的内容 – “编辑点”。

在此处输入图像描述

我面临几个问题:

  1. 我的路径有“线条” – >每个只有一个像素大小。 我只想选择“关键点”。 我怎么做? 这是“Flatten”的逆转,找不到这样的function。

  2. 是否存在.Net函数来绘制小的蓝色矩形,以及路径周围的小绿圈? 以及每个选定点周围的矩形怎么样? 在此处输入图像描述

每个帮助,甚至部分,将不胜感激。

对于你的问题的第一部分,请看看这篇文章 ,它有一个List的缩减function。 请注意, GraphicsPath.PathPoints集合是只读的,因此您必须从简化点列表重新创建路径。

关于第二部分的几点评论:

  • 没有内置例程来创建句柄。 也不要让他们做任何事情。 所以你需要为它们编码。

  • 我附加了一个简单的类MoveLabel ,可用于此。 它可以放在控件上或添加到其Controls集合中。 然后你可以移动它。 我添加了一个回调函数MoveAction来处理鼠标释放时的结果。

你可以添加..

 public delegate void Moved(MoveLabel sender); 

..到表单类,或者,为了避免Form1引用,在表单类之外,但在MoveLabel范围内。

它可以直接用于在点列表中移动点:

在面板上创建它:

 var lab= new MoveLabel(Color.CadetBlue, 9, Point.Round(points[i]), i); lab.Parent = panel; lab.MoveAction = moved; 

一个简单的处理function:

 void moved(MoveLabel sender) { points[sender.PointIndex] = new Point(sender.Left - sender.Width / 2, sender.Top - sender.Height / 2); panel.Invalidate(); } 

请注意, GraphicsPath.PathPoints是只读的,因此我们必须从新的点列表重新创建路径! 实际上可以在代码中修改单个PathPoints ,但结果不会粘; 所以必须将PathPoints复制到PointF[] ,在那里修改它们并重新创建路径。 对于复杂路径,最好使用此过载 ..

如果要实现旋转(或其他转换),可以使用GraphicsPath.Transform函数。 您可以使用可移动标签来确定旋转或缩放数据。这是我的最小MoveLabel类:

 public class MoveLabel : Label { public Form1.Moved MoveAction { get; set; } public int PointIndex { get; set; } private Point mDown = Point.Empty; public MoveLabel() { MouseDown += (ss, ee) => { mDown = ee.Location; }; MouseMove += (ss, ee) => { if (ee.Button.HasFlag(MouseButtons.Left)) { Location = new Point(Left + ee.X - Width / 2, Top + ee.Y - Height / 2); mDown = Location; } }; MouseUp += (ss, ee) => { if (MoveAction != null) MoveAction(this); }; } public MoveLabel(Color c, int size, Point location, int pointIndex) : this() { BackColor = Color.CadetBlue; Size = new Size(size, size); Location = location; PointIndex = pointIndex; } } 

这也适用于从贝塞尔曲线移动点。 通过添加调用MoveAction(this);MouseMove linq代码,你可以得到实时更新..确保Panels是DoubleBuffered为此:-)

例:

在此处输入图像描述


顺便说一句:我刚刚发现这篇文章 ,它显示了曲线或任何其他GDI +矢量绘图可以轻松保存到emf ,从而保持矢量质量!