为什么我的程序从左上角开始绘制所有线条?如何改变这一点?

2024-02-17

我编写了一个程序,该程序应该用线连接鼠标点击生成的 10 个点。

我遇到以下问题:

它从左上角绘制所有线条。 我可以认为解决方案是将第一个点设置为第一个鼠标单击,但我不知道该怎么做。

code:


    public partial class Form1 : Form

    {
        Point[] punten = new Point[10];
        private int kliks = 0;
        private int lijst = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {

           
         kliks = kliks + 1;
            lijst = kliks;
            punten[lijst] = e.Location;

            if (lijst < 9)


            {
                punten[lijst] = e.Location;

            }

            else
            {

                Pen pen = new Pen(Color.Blue);
                Graphics papier = this.CreateGraphics();
                papier.DrawLines(pen, punten);
            }
        }
    }
}

        

您面临的问题是使用固定大小的数组。每个条目默认为一个点(0,0)所以Drawlines()方法绘制 10 个元素,甚至是那些不是通过鼠标单击设置的元素。这导致最后几个点从原点开始(0,0)。此外,还有一个有缺陷的实现,即要保留哪些点击以及使用时发生了多少次点击kliks and lijst为了同样的事情。

这是 C#,最好学习如何分离跟踪鼠标点击的数据模型和绘制线条的显示代码。

PointHistory.cs

考虑以下使用数组的类Point跟踪鼠标点击。该类使用要保留的最大点数进行初始化(例如,10)。有一些方法可以添加点AddPoint(point)并删除最旧的点RemoveFirstPoint()。定义的点数可通过.Count财产。

最后,GetPoints()方法,返回仅包含已定义元素的数组副本。该方法用在绘制线条的代码中。

using System;
using System.Linq;

public class PointHistory
{
    private readonly Point[] points;
    private readonly int maxPoints;
    private int count;

    public PointHistory(int pointCapacity)
    {
        count = 0;
        maxPoints = pointCapacity;
        points = new Point[pointCapacity];
    }

    public Point[] GetPoints() { return points.Take(count).ToArray(); }
    public int Count { get => count; }
    public int Capacity { get => maxPoints; }
    public void AddPoint(Point point)
    {
        if (count < maxPoints)
        {
            points[count++] = point;
        }
    }
    public void RemoveFirstPoint()
    {
        if (count > 0)
        {
            for (int i = 0; i < count - 1; i++)
            {
                points[i] = points[i + 1];
            }
            count--;
        }
    }
}

Form1.cs

另一个问题是你的绘图,它需要发生在Paint事件处理程序。用你的MouseClick修改点列表的事件,以及Paint进行绘图的事件。

public partial class Form1 : Form
{
    readonly PointHistory history;

    public Form1()
    {
        InitializeComponent();

        history = new PointHistory(10);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        this.MouseClick += Form1_MouseClick;
        this.Paint += Form1_Paint;
    }

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            history.AddPoint(e.Location);
        }
        else if (e.Button == MouseButtons.Right)
        {
            history.RemoveFirstPoint();
            history.AddPoint(e.Location);
        }
        this.Invalidate();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        if (history.Count >= 2)
        {
            e.Graphics.DrawLines(Pens.Blue, history.GetPoints());
        }
        foreach (var point in history.GetPoints())
        {
            e.Graphics.FillEllipse(Brushes.Blue, point.X - 2, point.Y - 2, 4, 4);
        }
    }

}

我添加了一些额外的代码来在鼠标点击时添加小点以获得更好的视觉效果。

左键单击尝试将点添加到鼠标单击的历史记录中,最多达到构造函数中设置的限制PointHistory。单击鼠标右键会先删除最旧的点,然后再添加新点。


根据评论,我想提供一个下面的版本,它没有为逻辑定义单独的类,并且一切都是在内部完成的Form1班级。也没有高级库,例如Linq被使用

public partial class Form1 : Form
{
    private readonly Point[] points;
    private int count;

    public Form1()
    {
        InitializeComponent();

        points = new Point[10];
        count = 0;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        this.Paint += Form1_Paint;
        this.MouseClick += Form1_MouseClick;
    }

    public Point[] GetPoints()
    {
        Point[] results = new Point[count];
        for (int i = 0; i < count; i++)
        {
            results[i] = points[i];
        }
        return results;

        // Alternative to the loop above
        //
        //Array.Copy(points, results, count);
        //return results;
    }
    public void AddPoint(Point point)
    {
        if (count < points.Length)
        {
            points[count++] = point;
        }
    }
    public void RemoveFirstPoint()
    {
        if (count > 0)
        {
            for (int i = 0; i < count - 1; i++)
            {
                points[i] = points[i + 1];
            }
            count--;
        }
    }

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            AddPoint(e.Location);
        }
        else if (e.Button == MouseButtons.Right)
        {
            RemoveFirstPoint();
            AddPoint(e.Location);
        }
        this.Invalidate();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        Point[] mouseClicks = GetPoints();
        if (count >= 2)
        {
            e.Graphics.DrawLines(Pens.Blue, mouseClicks);
        }
        foreach (var point in mouseClicks)
        {
            e.Graphics.FillEllipse(Brushes.Blue, point.X - 2, point.Y - 2, 4, 4);
        }
    }

}

主要看方法是GetPoints()它返回一个点数组have通过鼠标单击定义并忽略任何尚未定义的点。

有一个替代实现,注释了用途Array.Copy()而不是循环,这将有助于更好的实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的程序从左上角开始绘制所有线条?如何改变这一点? 的相关文章

随机推荐