确保两个随机形状永远不会彼此靠近或重叠

Ensure two random shapes are never near each other or overlapping

var random = new Random();
        Canvas.SetLeft(rectangle, random.Next((int)(ImageCanvas.Width - 100)));
        Canvas.SetTop(rectangle, random.Next((int)(ImageCanvas.Height - 100)));
        return rectangle;

所以上面的代码只是随机设置了将出现在 canvas 上的矩形的顶部和左侧位置。如果我想让多个矩形出现在屏幕上,我可以很容易地重用这段代码,但是我遇到的麻烦是调整代码,使每个矩形永远不会相互重叠。

我想也许做一个 while 循环,使 运行 random.Next((int)(ImageCanvas.Height - 100)) 连续不断,直到它不等于之前的随机数。 .. 但这并不完美。形状很大,因此 X 或 Y 坐标略有不同并不能防止重叠。它们在某种程度上需要彼此之间至少有 50 像素的距离或其他距离,以防止其他矩形之间的任何重叠。

假设您的 Canvas 相当大,即矩形不会占据大量区域,很可能只需随机生成矩形(如您的示例代码),然后检查以确保它们不与之前选择的任何矩形重叠。

请注意 "overlaps with another rectangle" 与 "has a non-empty intersection with another rectangle" 实际上是一样的。 .NET 提供了该功能;对于 WPF,您应该使用 System.Windows.Rect 结构。它甚至有一个 IntersectsWith() 方法,在一次调用中提供您需要的信息(否则您必须一步获得交集,然后在第二步检查结果是否为空)。

整个事情可能看起来像这样:

List<Rectangle> GenerateRectangles(Canvas canvas, int count, Size size)
{
    Random random = new Random();
    List<Rect> rectangles = new List<Rect>(count);

    while (count-- > 0)
    {
        Rect rect;

        do
        {
            rect = new Rect(random.Next((int)(canvas.Width - size.Width),
                (int)(canvas.Height - size.Height), size.Width, size.Height);
        } while (rectangles.Any(r => r.IntersectsWith(rect));

        rectangles.Add(rect);
    }

    return rectangles.Select(r =>
         {
             Rectangle rectangle = new Rectangle();

             rectangle.Width = r.Width;
             rectangle.Height = r.Height;
             canvas.SetLeft(rectangle, r.Left);
             canvas.SetTop(rectangle, r.Top);

             return rectangle;
         }).ToList();
}

如果您要处理更受限的区域 and/or 和更多的矩形,您会想要更复杂的东西。对于大量矩形,上面的方法不能很好地缩放,尤其是在碰撞概率很高的情况下。但是对于您既定的目标,它应该可以正常工作。