如何确定矩形何时重叠或相交?

2023-12-01

我找到了如何绘制矩形和一些代码来查找两个矩形何时重叠,但我无法连接这些过程。

我有我想要的两个矩形,但无法确定它们是否相交,然后将此信息添加到列表框。

这是我的代码:

public partial class Form1 : Form
{
    Graphics g;
    Pen p;
    Point cursor;

    int k = 0;
    Point[] tocke = new Point[2];
    public Form1()
    {
        InitializeComponent();
        g = this.CreateGraphics();
        p = new Pen(Color.Black, 3);
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        cursor = this.PointToClient(Cursor.Position);
        statusMisa.Text = "X: " + cursor.X + " Y: " + cursor.Y;
    }

    private void Form1_Click(object sender, EventArgs e)
    {
        bool Preklapanje(int l1x, int l1y, int l2x, int l2y, int r1x, int r1y, int r2x, int r2y)
        {
            if (l1x >= r2x || l2x >= r1x)
            {
                return false;
            }

            if (l1y <= r2y || l2y <= r1y)
            {
                return false;
            }
            return true;
        }

        List<int> pozX = new List<int>();
        List<int> pozY = new List<int>();
        if (checkCrtanje.Checked == true)
        {
            Rectangle rect = new Rectangle(cursor.X - 50, cursor.Y - 50, 100, 100);
            if (k < 2)
            {
                g.DrawRectangle(p, rect);
                tocke[k++] = new Point(cursor.X, cursor.Y);
                listBox1.Items.Add("X: " + cursor.X + " Y: " + cursor.Y);
                pozX.Add(cursor.X);
                pozY.Add(cursor.Y);
            }
            else
            {
                MessageBox.Show("Možeš nacrtati samo dva kvadrata!");
            }
        }

        if (k == 3)
        {
            if (Preklapanje(pozX[0] - 50, pozY[0] - 50, pozX[0] + 50, pozY[0] + 50, pozX[1] - 50, pozY[1] - 50, pozX[1] + 50, pozY[1] + 50))
            {
                listBox1.Items.Add("Preklapaju se.");
            }
            else
            {
                listBox1.Items.Add("Ne preklapaju se.");
            }
        }
    }
}

► 如前所述,您不应该使用CreateGraphics()在 Control 的表面上绘制:该对象变得无效(属于past)一旦执行绘图的 Control 失效(重新绘制)。

所有具有可绘制表面的控件,都会引发Paint事件并有一个OnPaint我们可以重写来执行自定义绘画的方法(OnPaint方法负责提高Paint事件,所以我们只需要处理一个)。

事件和方法的参数代表一个绘制事件参数对象,它提供了一个fresh Graphics我们可以用来绘画的对象。

我们可以调用无效()需要时重新绘制控件的方法。该方法会导致新的生成PaintEventArgs对象(因此,一个新的 Graphics 对象)。之后OnPaint方法被调用,这反过来又引发 Paint 事件。

► 要确定一个矩形是否与另一个(或多个)矩形相交,我们可以使用矩形.IntersetWith()方法(它返回true or false)和矩形.相交()方法 → 这用于生成一个表示其他两个矩形的交集的矩形。

也可以看看:
矩形.包含([矩形])
矩形.Union([矩形a],[矩形b]).

在这里,我使用一些集合来存储当前绘制的形状及其交集(只是矩形,但您可以使用以下命令构建更复杂的形状)图形路径对象):

  • A List<Rectangle> (rects)它存储已经创建的矩形。
  • A List<Rectangle> (intersections),存储交集属于过去(已经绘制了交叉点)。
  • A List<Rectangle> (currentIntersects),用于临时存储绘制新矩形形状时生成的交集,以便我们可以使用不同的颜色(一旦松开鼠标按钮,该集合即为fixed并添加到intersections收藏)。
  • 矩形结构(currentRect)它代表当前正在表面上绘制的矩形(当释放鼠标按钮时,该对象被添加到rects收藏)。
  • 点结构(startPosition),用于存储当前绘制的 Rectangle 的初始位置。当调用 OnMouseDown 方法时(当生成新的矩形形状时),它会重置。

► 要使用此代码,请创建一个新表单并将您在此处找到的代码粘贴到其代码文件中。不需要订阅任何事件:因为我们在表单上绘图,所以我重写了它的方法(OnPaint, OnMouseDown, OnMouseUp, OnMouseMove),不使用任何事件。
您可以对自定义控件或用户控件执行相同的操作。

要将这些集合或仅将交集集合添加到例如列表框以直观地处理集合,请参阅此处(currentIntersects and intersections集合已包含信息):

如何调用使用 PaintEventArgs 和坐标变量的方法

NOTE:
► 在这里,在OnPaint方法重写,我没有调用base.OnPaint(),因此不会生成事件。这会稍微加快该过程,但请记住,订阅表单的 Paint 事件是没有用的。

► 您需要激活双缓冲:(设置DoubleBuffered = true),否则你会注意到很多闪烁(这是很正常的)。

它是这样工作的:

Drawing Rectangles Intersections


public partial class FormDrawings : Form
{
    private List<Rectangle> rects = new List<Rectangle>();
    private List<Rectangle> intersections = new List<Rectangle>();
    private List<Rectangle> currentIntersects = new List<Rectangle>();

    private Rectangle currentRect = Rectangle.Empty;
    private Point startPosition = Point.Empty;
    private float penSize = 2.0f;

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        if (e.Button == MouseButtons.Left) {
            startPosition = e.Location;
            currentRect = new Rectangle(startPosition, Size.Empty);
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (e.Button == MouseButtons.Left) {
            if (e.Y < startPosition.Y) { currentRect.Location = new Point(currentRect.X, e.Y); }
            if (e.X < startPosition.X) { currentRect.Location = new Point(e.X, currentRect.Y); }

            currentRect.Size = new Size(Math.Abs(startPosition.X - e.X), Math.Abs(startPosition.Y - e.Y));

            currentIntersects.Clear();
            foreach (var rect in rects) {
                if (currentRect.IntersectsWith(rect)) {
                    currentIntersects.Add(Rectangle.Intersect(currentRect, rect));
                }
            }
            this.Invalidate();
        }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        if (currentRect.Size != Size.Empty) rects.Add(currentRect);
        if (currentIntersects.Count > 0) {
            intersections.AddRange(currentIntersects);
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (var borderPen = new Pen(Color.LightGreen, penSize))
        using (var iBrush = new SolidBrush(Color.FromArgb(128, Color.Orange)))
        using (var crBrush = new SolidBrush(Color.FromArgb(128, Color.DeepSkyBlue))) {

            intersections.ForEach(r => e.Graphics.FillRectangle(iBrush, r));
            currentIntersects.ForEach(r => e.Graphics.FillRectangle(crBrush, r));

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

如何确定矩形何时重叠或相交? 的相关文章

随机推荐