最高のパフォーマンスに近づくには、独自のデータでさまざまなアルゴリズムを比較する必要があります。Point-In-Polygon アルゴリズムのいくつかを比較したところ、レイキャスティングが最高のパフォーマンスを提供することがわかりました。比較は次のとおりです。よく書かれたレイキャスティング アルゴリズムの実装については、こちらを参照してください。
これは高速で単純な部分でした。次のステップでは、2 つのポリゴンをマージします。ポリゴンが凸状の場合、より近い2つの頂点を接続できますが、それらが凹状である可能性があると言っているため(または、エッジに余分な頂点がある凸状のポリゴンでさえ)、より近いコーナーは機能しません. 例えば:
接続線がポリゴンのエッジと交差しない各ポリゴンから 1 つの頂点を選択する必要があります。2 つの線の交点を見つけるには、次のようにします。
function Zero(const Value: Double): Boolean;
const
Epsilon = 1E-10;
begin
Result := Abs(Value) < Epsilon;
end;
function IntersectLines(const X11, Y11, X12, Y12, X21, Y21, X22, Y22: Double;
out X, Y: Double): Boolean;
var
A1, B1, C1, A2, B2, C2, D: Double;
begin
A1 := Y12 - Y11;
B1 := X11 - X12;
C1 := A1 * X11 + B1 * Y11;
A2 := Y22 - Y21;
B2 := X21 - X22;
C2 := A2 * X21 + B2 * Y21;
D := A1 * B2 - A2 * B1;
if Zero(D) then
Result := False // Lines are parallel
else
begin
X = (B2 * C1 - B1 * C2) / D;
Y = (A1 * C2 - A2 * C1) / D;
end;
end;
ただし、交点を見つけただけでは、選択した頂点が適切ではないということにはならないことに注意してください。これは、線分を扱っているため、交点は線分内にある必要があるためです。それを見つけるには、ポイントがセグメントの境界ボックス内にあるかどうかを確認できます。たとえば、この図では、1 と 2 が選択された頂点であり、3 がエッジと交差する線の交点ですが、3 は 1 と 2 を覆うバウンディング ボックスの内側にはありません。
選択した頂点の各カップルの交差線は、バウンディング ボックス内の各ポリゴンの少なくとも 2 つのエッジ (選択した頂点で交わるエッジ) と交差することに注意してください。
その後、選択した頂点から外側のポリゴンを分割し、それらの間に内側のポリゴンのリダイレクトされた頂点を挿入する必要があります。
最後の言葉として、私は言うべきです:はい!これらすべてについて多くの理論がありますが、独自の理論を見つける必要があります。あなたが言ったように、1 つのポリゴンはすべて他のポリゴンの内側にあるということは、それらが体系的に生成されるか、文字境界のように事前に定義されていることを意味します。次に、説明したすべてのアルゴリズムを変更して、独自のケースでより良いパフォーマンスを達成できる場合があります。