编辑FreeShape的点
我有一些GUI让用户绘制costimized GraphicsPath。 我使用GraphicsPath AddLine函数创建了它。
现在,我想实现您在附加的Microsoft Word图像中看到的内容 – “编辑点”。
我面临几个问题:
-
我的路径有“线条” – >每个只有一个像素大小。 我只想选择“关键点”。 我怎么做? 这是“Flatten”的逆转,找不到这样的function。
-
是否存在.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
,从而保持矢量质量!