c# - 如何阻止 GraphicsPath 关闭

标签 c# .net winforms linq gdi+

我正在尝试制作一个橡皮擦工具,可以从 GraphicsPath 中删除点。到目前为止,我的代码允许用户在表单上绘画,并且“删除”按钮应该删除 GraphicsPath 的前 20 个点。它会一直工作,直到制作出两张可区分的图画,然后按下“删除”按钮 - 如图所示,两张图画连接在一起。我怀疑 GraphicsPath 会自行关闭(连接每个点)。

有没有办法阻止GraphicsPath连接每个点?

这是我的完整代码。我认为最相关的部分是底部的函数。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;

namespace Cartographer
{
    public partial class testform : Form
    {

        private GraphicsPath _drawingPath = new GraphicsPath();
        private Point lastMouseLocation;
        private bool drawing = false;

        public testform()
        {
            InitializeComponent();
        }

        private void testform_Load(object sender, EventArgs e)
        {
            this.Paint += Testform_Paint;
            this.MouseMove += Testform_MouseMove;

            this.DoubleBuffered = true;
        }

        private void Testform_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                drawing = true;
                _drawingPath.AddLine(lastMouseLocation, e.Location);
                Invalidate();
            }

            if (e.Button == MouseButtons.None && drawing)
            {
                drawing = false;
                _drawingPath.StartFigure(); // problem is not due to this line


            }
            lastMouseLocation = e.Location;
        }

        private void Testform_Paint(object sender, PaintEventArgs e)
        {

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            using (SolidBrush b = new SolidBrush(Color.Blue))
            using (Pen p = new Pen(b, 51))
            {
                p.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Round;
                p.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;

                e.Graphics.DrawPath(p, _drawingPath);

            }

            using (SolidBrush b = new SolidBrush(Color.LightGreen))
            using (Pen p = new Pen(b, 50))
            {
                p.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Round;
                p.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;

                e.Graphics.DrawPath(p, _drawingPath);
            }

        }

        private void btnErase_Click(object sender, EventArgs e)
        {
            List<PointF> ptsList = new List<PointF>();
            for (int i = 0; i < 20; i++)
            {
                ptsList.Add(_drawingPath.PathData.Points[i]);
            }

            _drawingPath = ErasePointsFromPath(_drawingPath, ptsList.ToArray<PointF>());
            this.Invalidate();
        }

        private GraphicsPath ErasePointsFromPath(GraphicsPath path, PointF[] toRemove)
        {
            PointF[] newPoints = path.PathData.Points.Except<PointF>(toRemove).ToArray<PointF>();
            byte[] types = new byte[newPoints.Length];
            for (int i = 0; i < newPoints.Length; i++)
            {
                types[i] = 1;
            }

            GraphicsPath ret = new GraphicsPath(newPoints, types);
            //ret.SetMarkers();
            return ret;
        }
    }
}

这就是发生的事情。图中的两条圆形线应该是分开的,并且不由对角线连接。

thing

最佳答案

当您从路径中删除点时,您可以通过将它们复制到新路径来执行此操作,排除要删除的点。但您并没有从第一条路径复制相应的点类型信息;相反,无论出于何种原因,您都将所有点类型重置为 1。这会丢失有关路径中每个图形的起始位置的信息。因此,新路径会看到一个长连接的图形,这解释了您所看到的内容。
如果您想从路径中删除前n个点,您可以尝试这样的操作:

private void btnErase_Click(object sender, EventArgs e)
{
    int numberOfPointsToErase = 20;

    if (_drawingPath.PointCount > numberOfPointsToErase)
    {
        _drawingPath = new GraphicsPath(
            _drawingPath.PathPoints.Skip(numberOfPointsToErase).ToArray(),
            _drawingPath.PathTypes.Skip(numberOfPointsToErase).ToArray()
        );
    }
    else
    {
        _drawingPath.Reset();
    }

    this.Invalidate();
}

关于c# - 如何阻止 GraphicsPath 关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47684696/

相关文章:

c# - 如何基于 DropDownList 选择验证具有 RegularExpression 的 TextBox?

.net - 使用 Connect-AzAccount 服务主体从 dotnet 中调用 PowerShell 脚本并进行身份验证

c# - 在静态方法中使用 Winform 对象

c# - 隐藏表单上的最小化和最大化按钮而不隐藏标题

.net - 如何判断用户是否使用笔记本电脑

c# - 显示希伯来语 sqlplus

c# - 将 JSON 反序列化到 SQLite 数据库中

c# - 运行 .cs 文件 - visual studio 2012

.net - 2(3)关于T4模板,获取正在处理的主文件名,能够结束处理的问题?

c# - Roslyn 代码分析器——什么时候应该使用 "this."?