找到重叠相同矩形的多个矩形的总重叠百分比?

时间:2012-06-19 15:06:44

标签: vb.net intersection system.drawing overlap

我有一个System.Drawing.RectangleF个对象列表,这些对象都与同一个RectangleF对象重叠。在下面的图片中,3个重叠的矩形将是粉红色,黄色和红色矩形。我的主要矩形是浅蓝色矩形。

enter image description here

第二张图片: enter image description here

我知道对于RectangleF个对象,我可以使用Intersect()方法返回另一个代表重叠的RectangleF对象。但据我所知,这只有在比较两个矩形时才有效。

我的问题是:我怎样才能确定TOTAL面积/百分比(即与光相比时红色,黄色和粉红色矩形的组合总重叠蓝色矩形 - 但它需要足够聪明,不要计算红色和黄色重叠两次的区域,粉红色和黄色相同的区域?

注意:绿线表示我正在寻找的区域,只是不可见的蓝色矩形的总面积。

更新:我添加了第二张图片,以进一步展示我正在寻找的内容。在第二张图片中,勃艮第矩形的存在应该对覆盖的总百分比没有影响,因为该区域已经被黄色和绿色矩形覆盖。

2 个答案:

答案 0 :(得分:2)

好的我觉得我找到了一个使用Region的解决方案,似乎适用于我上面的两个示例图片:

Private Function TotalCoveredAreaPercent(ByVal oRectToCheck As RectangleF, ByVal oOverlappingRects As List(Of RectangleF)) As Double

    Dim oRegion As New Region(oRectToCheck)
    Dim dTotalVisibleArea As Double = 0
    Dim dTotalCoveredArea As Double = 0

    'now we need to exclude the intersection of our 
    'overlapping rectangles with our main rectangle:
    For Each oOverlappingRect As RectangleF In oOverlappingRects

        oRegion.Exclude(RectangleF.Intersect(oRectToCheck, oOverlappingRect))

    Next

    'now we have access to the non-overlapping 
    'rectangles that make up the visible area of our main rectangle:
    Dim oVisibleRects As RectangleF()

    oVisibleRects = oRegion.GetRegionScans(New Drawing2D.Matrix())

    'add the area of the visible rectangles together 
    'to find the total visible area of our main rectangle:
    For Each oVisibleRect As RectangleF In oVisibleRects
        dTotalVisibleArea += AreaOf(oVisibleRect)
    Next

    Dim dPercentVisible As Double = dTotalVisibleArea / AreaOf(oRectToCheck) * 100

    'percent covered is 100 - the visible percentage:
    Return (100 - dPercentVisible)

End Function

这似乎运作得很好,而且非常简单。

答案 1 :(得分:1)

这是我的算法。关键是我们正在减去重叠的重叠。

    Dim baseRect As New RectangleF(10, 10, 20, 20)
    Dim otherRectList As New List(Of RectangleF)
    otherRectList.Add(New RectangleF(5, 5, 10, 10))
    otherRectList.Add(New RectangleF(20, 20, 10, 10))
    otherRectList.Add(New RectangleF(10, 5, 10, 10))

    Dim overlapRectList As New List(Of RectangleF)
    For Each otherRect As RectangleF In otherRectList
      If RectangleF.Intersect(otherRect, baseRect) <> RectangleF.Empty Then
        overlapRectList.Add(RectangleF.Intersect(otherRect, baseRect))
      End If
    Next

    Dim totalArea As Single = 0
    For Each overlapRect As RectangleF In overlapRectList
      totalArea += overlapRect.Width * overlapRect.Height
    Next

    'Subtract out any overlaps that overlap each other
    For i = 0 To overlapRectList.Count - 2
      For j = i+1 To overlapRectList.Count - 1
        If i <> j Then
          If RectangleF.Intersect(overlapRectList(i), overlapRectList(j)) <> RectangleF.Empty Then
            Dim dupeRect As RectangleF = RectangleF.Intersect(overlapRectList(i), overlapRectList(j))
            totalArea -= dupeRect.Width * dupeRect.Height         
          End If
        End If
      Next
    Next

我修改了代码以考虑到tcarvin的注释。但是,我没有在方格纸上绘制出结果,看看这是否完全正确。一旦我有额外的时间,我会看着它。另请注意,我没有包含任何代码来处理少于2个交叉点的情况。