我有一个System.Drawing.RectangleF
个对象列表,这些对象都与同一个RectangleF
对象重叠。在下面的图片中,3个重叠的矩形将是粉红色,黄色和红色矩形。我的主要矩形是浅蓝色矩形。
第二张图片:
我知道对于RectangleF
个对象,我可以使用Intersect()
方法返回另一个代表重叠的RectangleF
对象。但据我所知,这只有在比较两个矩形时才有效。
我的问题是:我怎样才能确定TOTAL面积/百分比(即与光相比时红色,黄色和粉红色矩形的组合总重叠蓝色矩形 - 但它需要足够聪明,不要计算红色和黄色重叠两次的区域,粉红色和黄色相同的区域?
注意:绿线表示我正在寻找的区域,只是不可见的蓝色矩形的总面积。
更新:我添加了第二张图片,以进一步展示我正在寻找的内容。在第二张图片中,勃艮第矩形的存在应该对覆盖的总百分比没有影响,因为该区域已经被黄色和绿色矩形覆盖。
答案 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个交叉点的情况。