(このアプローチは、@GarethRees のものと同様の考え方に従います。最初に、包含をチェックする必要のないポリゴンのペアを安価に見つけます。チェックする必要があるペアの数が受け入れられるようになったら、正確な (高価な) ジオメトリを実行します。小切手。)
ポリゴンごとに外接する四角形、つまり左、右、上、下を計算するのは簡単なので、最初に計算してみましょう。左の例:p.L = min { x : (x,y) is a vertex of p }
時間はポイント数に比例します。
各ポリゴンを互いに比較する必要がないように、エリアを 2x2 グリッドに分割できます。領域の幅と高さがそれぞれ と で与えられると仮定すると、Dx
9つのDy
セットtop,bottom,left,right,topright,topleft,bottomright,bottomleft,rest
を作成して次の操作を実行できます。
for p in polygons:
in_top = p.B > Dy/2
in_bottom = p.T < Dy/2
in_left = p.R < Dx/2
in_right = p.L > Dx/2
if in_top:
if in_left:
add p to topleft
elsif in_right:
add p to topright
else:
add p to top
elsif in_bottom:
if in_left:
add p to bottomleft
elsif in_right:
add p to bottomright
else:
add p to bottom
if in_right and not (in_top or in_bottom):
add p to right
elsif in_left and not (in_top or in_bottom):
add p to left
if not (in_top or in_bottom or in_left or in_right):
add p to rest
これも線形時間です。各ポリゴンは、最も「密に」含まれるセクターにビニングされています。これによってあなたは何を得ましたか?たとえば、ポリゴンp
のleft
場合、 set との包含関係はあり得ないことがわかっているright
ので、それらを比較する必要はありません。同様に と の間bottomleft
、right
とbottomleft
などtopleft
。あなたの例では次のようになります。
Dx/2
+----------------------|---------------------+
| | |
| +----------------+ | +--------+ |
| | | | / | |
| | +--------+ | | / | |
|___|___|________|___|_|____ /__+===d(2)=+___|_ Dy/2
| | | | | | / | |
| | +---b(3)-+ | | / | +---+ |
| | | | +-----+ | | |
| +-----------c(2)-+ | e(2)+ |
| | |
+----------------------|----------------a(1)-+
そうrest = {a}, top = {}, bottom = {}, left = {b,c}, right = {d}
topleft = {}, topright = {}, bottomleft = {}, bottomright = {e}
したがって、基本的には、(高価な正確なチェックを使用して) 、b
、c
および他のすべてと比較する必要があります。包含は推移的であるため、 includes 、およびincludesに気付いた場合、 includesかどうかを確認する必要はありません。d
e
a
a
c
b
a
c
a
b
もう 1 つのポイントは、上記の推論を再帰的に適用できることです。たとえば、セットtopright
が大きすぎて好みに合わないとします。次に、そのサブリージョンをさらに分割することで、同じ手法を適用できます (簿記を正しく行う必要があるだけです)。