如何阻止GraphicsPath关闭

时间:2017-12-06 22:40:51

标签: 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 个答案:

答案 0 :(得分:1)

当您从正在执行此操作的路径中删除点时,将它们复制到新路径,排除要删除的路径。但是你也没有从第一条路径复制相应的点类型信息;相反,无论出于何种原因,您都将所有点类型重置为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();
}