3

System.Drawing.RectangleFすべてが同じオブジェクトに重なっているオブジェクトのリストがありRectangleFます。下の私の写真では、3 つの重なり合う長方形は、ピンク、黄色、赤の長方形になります。問題の私の主な長方形は水色の長方形です。

ここに画像の説明を入力

2 番目の画像: ここに画像の説明を入力

オブジェクトでは、オーバーラップを表す別のオブジェクトを返すメソッドをRectangleF使用できることを知っています。しかし、私が知る限り、これは 2 つの長方形を比較する場合にのみ機能します。Intersect()RectangleF

私の質問は次のとおりです。TOTAL面積/パーセンテージ(つまり、水色の長方形と比較した場合の赤、黄、ピンクの長方形の合計オーバーラップを合計したもの)をどのように決定できますか?赤と黄色が2 回重なり、ピンクと黄色も同じ)?

注: 緑色の線は、探している領域を表しており、表示されていない青い四角形の合計領域です。

更新:探しているものをさらに示すために、2番目の画像を追加しました。2 番目の画像では、ブルゴーニュの長方形の存在は、その領域が黄色と緑の長方形で既に覆われているため、カバーされた合計パーセントに影響を与えません。

4

2 に答える 2

2

RegionOK 、上記の両方のサンプル画像で機能しているように見えるを使用して解決策を見つけたと思います。

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 に答える