3

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

在此处输入图像描述

第二张图片: 在此处输入图像描述

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

我的问题是:如何确定总面积/百分比(即,与浅蓝色矩形相比,红色、黄色和粉红色矩形的总重叠总和- 但它需要足够聪明才能不计算面积红色和黄色重叠两次,粉色和黄色重叠)?

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

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

4

2 回答 2

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

这似乎工作得很好,而且很简单。

于 2012-06-20T13:26:47.303 回答
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 个交叉点的情况。

于 2012-06-19T22:09:10.583 回答