在图画的橡皮擦工具,当保留边界时

时间:2017-12-09 23:09:09

标签: c# .net winforms gdi+

我正在制作2D地图绘制工具并遇到问题。彩绘“土地”周围的边界充当“海岸”。当用户涂上更多的水时,土地应该用水刷去除/替换,但是海岸应该适应变化(因为海岸是实时绘制的)。

这是我目前的代码:

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;
            this.SetStyle(ControlStyles.Opaque, false);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        }

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

            if (e.Button == MouseButtons.None && drawing)
            {
                drawing = false;
                _drawingPath.StartFigure();
            }
            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.HighQuality;

            using (SolidBrush b = new SolidBrush(Color.FromArgb(100, Color.Brown)))
            using (Pen p = new Pen(b, 55))
            {
                p.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                p.EndCap = System.Drawing.Drawing2D.LineCap.Round;

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

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

                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)
        {
            GraphicsPath ret = new GraphicsPath(
                path.PathData.Points.Skip(20).ToArray(), 
                path.PathData.Types.Skip(20).ToArray());

            return ret;
        }
    }
}

我希望我的软件有这样的边界,即使水被刷过陆地:

pic 1

现在它看起来像这样(这很好,它用于测试)但是我无法微调那块土地中间的那条小河/湖,因为如果我简单地在它上面画海岸就会消失

enter image description here

我有另一个与GdipWindingModeOutline一起使用的工作版本,所以如果有办法做到这一点我可以适应。

为了记录,我尝试从GraphicsPath中删除点,但是删除了大块而不是我想要的简单“橡皮擦工具”类型的功能。

谢谢!

0 个答案:

没有答案