C# 自由图形的编辑点

C# 自由图形的编辑点,c#,.net,graphicspath,C#,.net,Graphicspath,我有一些图形用户界面,让用户绘制成本最小化的图形。 我使用GraphicsPath AddLine函数创建了它 现在,我想实现您在附加的Microsoft Word图像“编辑点”中看到的内容 我面临着几个问题: 我的路径有无数条“线”->每一条线只有一个像素大小。我只想选择“关键点”。我该怎么做?这是一种“扁平化”的反转,找不到这样的函数 是否有一个现有的.Net函数来绘制蓝色的小矩形和环绕路径的绿色小圆圈?那么每个选定点周围的矩形呢? 每一个帮助,即使是部分帮助,都将不胜感激。对于问题的第

我有一些图形用户界面,让用户绘制成本最小化的图形。 我使用GraphicsPath AddLine函数创建了它

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

我面临着几个问题:

  • 我的路径有无数条“线”->每一条线只有一个像素大小。我只想选择“关键点”。我该怎么做?这是一种“扁平化”的反转,找不到这样的函数

  • 是否有一个现有的.Net函数来绘制蓝色的小矩形和环绕路径的绿色小圆圈?那么每个选定点周围的矩形呢?


  • 每一个帮助,即使是部分帮助,都将不胜感激。

    对于问题的第一部分,请看一看,它具有
    列表的缩减功能。请注意,
    GraphicsPath.PathPoints
    集合是只读的,因此必须从减少的点列表中重新创建路径

    关于第二部分的几点意见:

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

    • 我附加了一个简单的类
      MoveLabel
      ,可用于此。它可以放在控件上,也可以添加到控件的
      集合中。然后你可以移动它。我添加了一个回调函数
      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
    ,但结果并不一致;因此,必须将
    路径点
    复制到
    点f[]
    ,在那里修改它们并重新创建路径。对于复杂路径,最好使用

    如果要实现旋转(或其他变换),可以使用该函数。可以使用可移动标签来确定旋转或缩放数据。。 这是我的最小
    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;
        }
    }
    
    这也可以很好地从bezier曲线移动点。通过添加调用
    MoveAction(此)
    MouseMove
    linq代码,您可以获得实时更新。。确保
    面板
    适用于此:-)

    例如:


    顺便说一句:我刚刚发现了一个例子,它显示了曲线或任何其他GDI+矢量图形可以多么容易地保存到
    emf
    ,保持矢量质量



    更新:代替
    面板
    ,该面板是
    容器
    控件,并不真正用于绘制。您可以使用
    图片盒
    标签
    (使用
    自动大小=false
    );两者都启用了“开箱即用”的
    双缓冲
    属性,并且比
    面板
    do更好地支持绘图。

    两个account上的否。1) 您只能通过在点上循环、计算(累积)坡度并标记所有点以删除,来尝试减少点的数量,直到坡度变化超过某个ε要编写Simplefy函数,请执行以下操作:2) 只要您的路径仅由直线组成,就没有控制点。您可以检查路径数据中的其他点阵列,其中包含要检查的点类型。谢谢!你知道现有的降低分数的方法吗?我决定写一个快速的方法。你可以看到,谢谢!让我开心。:)我有函数数学…一如既往-你的答案是完整的,详细的,只是“扔”我海峡前进。太遗憾了,我不能投票。。