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

时间:2015-02-06 23:46:58

标签: c# wpf random position shape

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

因此上面的代码只是随机设置将出现在画布上的矩形的顶部和左侧位置。如果我想在屏幕上显示多个矩形,我可以轻松地重复使用此代码,但是我遇到的麻烦就是调整代码以使每个矩形永远不会相互重叠。

我想过可能会做一个持续运行random.Next((int)(ImageCanvas.Height - 100))的while循环,直到它不等于之前的随机...但这并不完美。形状非常大,因此具有略微不同的X或Y坐标并不能防止重叠。为了防止其他矩形之间出现任何重叠,它们之间需要至少相隔50像素距离。

1 个答案:

答案 0 :(得分:2)

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

请注意"与另一个矩形重叠"与#34;实际上是一样的,与另一个矩形有一个非空交集"。 .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();
}

如果你处理的是更受限制的区域和/或更多的矩形,你会想要更复杂的东西。以上不会很好地适用于大量矩形,特别是在碰撞概率很高的情况下。但是对于你声明的目标,它应该可以正常工作。