これは私の頭の上からそれがうまくいくように聞こえるものです:
次のように、2 つのキーと四角形 + ブール値のリストを使用して辞書を作成します。
Dictionary< Double、List< KeyValuePair< Rectangle、Boolean>>> 四角形;
セット内の各四角形について、x0 と x1 の値に対応するリストを見つけ、そのリストに四角形を追加します。x0 の場合は true、x1 の場合は false のブール値を指定します。このようにして、各長方形が x 方向に入る (true) または出る (false) すべての x 座標の完全なリストが得られます。
そのディクショナリからすべてのキー (すべての個別の x 座標) を取得し、並べ替えて、順番にループし、現在の x 値と次の x 値の両方を取得できることを確認します (両方が必要です)。 )。これにより、長方形の個々のストリップが得られます
- 現在見ている四角形のセットを維持します。これは最初は空です。ポイント3で繰り返し処理するx値ごとに、長方形が真の値で登録されている場合はセットに追加し、そうでない場合は削除します。
- ストリップの場合、長方形を y 座標で並べ替えます
- 重なり合う距離を数えながら、ストリップ内の長方形をループします(これを効率的に行う方法はまだわかりません)
- ストリップの幅と重なり合う距離の高さの積を計算して、面積を取得します
例、5 つの長方形、a から e までを重ねて描画:
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaadddddddddddddddddddddddddddddbbbbbb
aaaaaaaadddddddddddddddddddddddddddddbbbbbb
ddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddd
ddddddddddddddeeeeeeeeeeeeeeeeee
ddddddddddddddeeeeeeeeeeeeeeeeee
ddddddddddddddeeeeeeeeeeeeeeeeee
ccccccccddddddddddddddeeeeeeeeeeeeeeeeee
ccccccccddddddddddddddeeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc
cccccccccccc
x座標のリストは次のとおりです。
v v v v v v v v v
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaaddd|dddddddddd|ddddddddddddddbb|bbb
|aaaaaaaddd|dddddddddd|ddddddddddddddbb|bbb
| ddd|dddddddddd|dddddddddddddd |
| ddd|dddddddddd|dddddddddddddd |
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
ccccccccddd|ddddddddddeeeeeeeeeeeeeeeeee
ccccccccddd|ddddddddddeeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc
cccccccccccc
リストは次のようになります (各 v には、0 から始まる座標が単純に与えられます):
0: +a, +c
1: +d
2: -c
3: -a
4: +e
5: +b
6: -d
7: -e
8: -b
したがって、各ストリップは次のようになります (上から下に並べ替えられた四角形):
0-1: a, c
1-2: a, d, c
2-3: a, d
3-4: d
4-5: d, e
5-6: b, d, e
6-7: b, e
7-8: b
各ストリップのオーバーラップは次のようになります。
0-1: none
1-2: a/d, d/c
2-3: a/d
3-4: none
4-5: d/e
5-6: b/d, d/e
6-7: none
7-8: none
上下チェックのソート + エンター/リーブ アルゴリズムのバリエーションも同様に実行可能であると思います。
- ストリップで現在分析している長方形を上から下に並べ替えます。同じ上座標を持つ長方形については、下座標でも並べ替えます
- y座標を反復処理し、長方形に入るとセットに追加し、長方形を離れるとセットから削除します
- セットに複数の長方形がある場合は常に、重複があります(現在見ている同じ上/下座標を持つすべての長方形を確実に追加/削除する場合、複数の重なり合う長方形は問題になりません
上記の 1-2 ストリップの場合、次のように繰り返します。
0. empty set, zero sum
1. enter a, add a to set (1 rectangle in set)
2. enter d, add d to set (>1 rectangles in set = overlap, store this y-coordinate)
3. leave a, remove a from set (now back from >1 rectangles in set, add to sum: y - stored_y
4. enter c, add c to set (>1 rectangles in set = overlap, store this y-coordinate)
5. leave d, remove d from set (now back from >1 rectangles in set, add to sum: y - stored_y)
6. multiply sum with width of strip to get overlapping areas
ここでも実際のセットを実際に維持する必要はありません。内部にある長方形の数だけです。これが1から2になるたびにyを保存し、2から1になるたびに現在のyを計算します- y を格納し、この差を合計します。
これが理解できることを願っています。私が言ったように、これは私の頭の上から外れており、まったくテストされていません。