编辑FreeShape的点

时间:2018-06-06 07:15:31

标签: c# .net graphicspath

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

现在我想实现您在附加的Microsoft Word图像中看到的内容 - "编辑点"。

enter image description here

我遇到了几个问题:

  1. 我的路径有"线" - >每个只有一个像素大小。我只想选择"关键点"。我怎么做?它是" Flatten"的逆转,无法找到这样的功能。

  2. 是否存在.Net函数来绘制小的蓝色矩形,以及路径周围的小绿圈?以及每个选定点周围的矩形怎么样? enter image description here

  3. 每个帮助,甚至是部分帮助都将受到赞赏。

1 个答案:

答案 0 :(得分:2)

对于问题的第一部分,请查看this post,它具有List<Point>的缩减功能。请注意,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;

一个简单的处理功能:

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[],在那里修改它们并重新创建路径。使用this overload ..

最适合复杂路径

如果要实现旋转(或其他转换),可以使用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); linq代码添加电话MouseMove,您可以获得实时更新。请确保Panels DoubleBuffered为此: - )

示例:

enter image description here

顺便说一句:我刚刚来到this post,它显示了曲线或任何其他GDI +矢量绘图可以轻松保存到emf,保留了矢量质量!