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

有没有办法防止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;
        }
    }
}


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

c# - 如何停止GraphicsPath关闭-LMLPHP

最佳答案

当您从路径中删除点时,您可以通过将其复制到新路径中来进行删除(不包括要删除的点)。但是,您也不会从第一条路径复制相应的点类型信息。相反,无论出于何种原因,您都将所有点类型重置为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();
}

10-07 14:57