确保两个随机形状永远不会彼此靠近或重叠
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 和更多的矩形,您会想要更复杂的东西。对于大量矩形,上面的方法不能很好地缩放,尤其是在碰撞概率很高的情况下。但是对于您既定的目标,它应该可以正常工作。
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 和更多的矩形,您会想要更复杂的东西。对于大量矩形,上面的方法不能很好地缩放,尤其是在碰撞概率很高的情况下。但是对于您既定的目标,它应该可以正常工作。