检查Canvas XAML中的矩形是否相交

时间:2014-05-27 23:17:25

标签: c# wpf xaml canvas

我有一个画布,我画了不同的矩形。我在集合中有矩形坐标。每次将一个矩形添加到画布时,我需要检查它是否超过其他现有矩形。 我检查画布中每个现有矩形的新矩形,以了解矩形是否与任何其他矩形重叠。 这是最有效的解决方案吗?

foreach(System.Windows.Shapes.Rectangle r in rectCollection)
            {
                IntersectionDetail d1 = r.RenderedGeometry.FillContainsWithDetail(this.rect.RenderedGeometry);
                if(d1 == IntersectionDetail.Intersects)
                {
                    MessageBox.Show("New Rectangle intersects with existing rectangle");
                }

            }

1 个答案:

答案 0 :(得分:3)

要检查您的矩形是否与其他矩形相交,在最坏的情况下您需要做的最小交互次数至少会经历一次;你无法避免这一事实。这意味着在最坏的情况下,您不能低于O(n)的复杂度。

这种复杂性可以通过单个循环实现,也可以简单地使用LINQ方法.Any(),只要有交叉点就会停止(所以我们可以得到{ {1}})。

在这里,最糟糕的情况是“没有交叉点”,因为您需要检查下一个矩形以查看该矩形是否会发生碰撞。最好的情况是第一次检查时的命中。

假设您的集合称为坐标,而您正在检查newRect的Rect,检查将变为:

O(1)

根据您的上次更新,很明显您没有集合中的“矩形坐标”,而是来自if (coordinates.Any(c => c.IntersectsWith(newRect))) { //There is overlapping } 的{​​{1}},这根本不是一回事。 Rectangle仅包含有关其宽度和高度的信息,而不包含其自身的位置。

您需要在循环之前将它们转换为Windows.Shapes,方法是使用它们在画布上的位置及其尺寸:

Rectangle

要排除边,你可以汇总你自己的扩展方法(作为个人喜好,我更喜欢保持我的ifs和lamdas清洁)

Rect

然而,逻辑与你的逻辑略有不同,所以如果它有效,请随意使用你想要的那个。基本上我使用的事实是,如果只有边界接触,交叉区域将只有一个维度。

因此检查将变为

IEnumerable<Rect> coordinates = rectCollection.Select(r => new Rect(Canvas.GetLeft(r), Canvas.GetTop(r), r.Width, r.Height));