凹型ポリゴンの内側に収まる最大の円を見つけるにはどうすればよいですか?
ブルートフォースアルゴリズムは、頂点数が50以下のポリゴンをリアルタイムで処理できる限り問題ありません。
この問題を解決する鍵は、最初に観察することです。任意のポリゴンの内側に収まる最大の円の中心は、次の点です。
どうして?円のエッジ上のすべての点がその中心から等距離にあるからです。定義により、最大の円は最大の半径を持ち、少なくとも2つの点でポリゴンに接触するため、ポリゴンから最も遠い内側の点を見つけた場合、円の中心を見つけます。
この問題は地理に現れ、任意の精度で繰り返し解決されます。それは、アクセス不能問題の極と呼ばれています。 Poles of Inaccessibility:A Algorithm Algorithm for the Remotest Places on Earth を参照してください。
基本的なアルゴリズムは次のように機能します。
1つのメモ、ポイントがポリゴンの内側にあるかどうかをテストする方法:問題のこの部分の最も簡単な解決策は、ポイントの右側に光線を投影することです。奇数のエッジと交差する場合は、ポリゴン内にあります。偶数なら外です。
また、任意のエッジまでの距離をテストする限り、2つのケースを検討する必要があります。
(2)簡単です。エッジまでの距離は、2つの頂点までの距離の最小値です。 (1)の場合、そのエッジ上の最も近いポイントは、テストしているポイントから開始して90度の角度でエッジと交差するポイントになります。 光線またはセグメントへの点の距離 を参照してください。
O(n log(n))アルゴリズム:
誰かが実用的な実装を探している場合に備えて、この問題を特定の精度で解決するより高速なアルゴリズムを設計し、それをJavaScriptライブラリーにしました。これは、@ cletusによって記述された反復グリッドアルゴリズムに似ていますが、グローバル最適を取得することが保証されており、実際には20〜40倍高速です。
確認してください: https://github.com/mapbox/polylabel
概要:理論的には、これはO(n)時間で実行できます。実際には、O(n log n)時間で実行できます。
一般化ボロノイ図
ポリゴンの頂点とエッジをサイトのセットと見なし、内部を「最も近い隣接セル」にテッセレーションすると、いわゆる(一般化された)ボロノイ図が得られます。ボロノイ図は、ノードとそれらを接続するエッジで構成されます。ノードのclearanceは、その定義するポリゴンフェースまでの距離です。
(ここでは、ポリゴンに穴さえあります。原理はまだ機能しています。)
ここで重要な観察は、最大内接円の中心がポリゴンの3つの面(頂点またはエッジ)に接触しており、他の面はこれ以上接近できないことです。したがって、中心はボロノイノード、つまり最大のクリアランスを持つノード上にある必要があります。
上記の例では、最大内接円の中心を示すノードは、2つのエッジとポリゴンの頂点に接しています。
ちなみに、内側の軸は、反射頂点から発するボロノイエッジが削除されたボロノイ図です。したがって、最大内接円の中心も中心軸上にあります。
出典: ブログ記事 ある時点での最大内接円の一般化を扱う私のブログ。そこでは、ボロノイ図と、最大内接円との関係について詳しく知ることができます。
アルゴリズムと実装
実際にボロノイ図を計算できます。ポイントとセグメントの最悪の場合のO(n log n)アルゴリズムは、Fortune、Aボロノイ図のスイープアルゴリズム、SoCG'86によって与えられます。開催されたソフトウェアパッケージ Vroni は、予想されるO(n log n)時間の複雑さで公開され、実際に最大内接円も計算されます。そして boost にも実装があるようです。
単純なポリゴン(つまり、穴がない)の場合、O(n)時間で実行される時間最適アルゴリズムは、Chin et al。、 によるものです)線形時間での単純な多角形の中心軸の検索 、1999。
ブルートフォース
ただし、ブルートフォースアルゴリズムで問題ないと述べたとおり、サイトのすべてのトリプレット(頂点とエッジ)を単純に試してみてはどうでしょうか。各トリプレットについて、Voronoiノードの候補、つまり3つのサイトまでの等距離の軌跡を見つけ、他のサイトが候補の最大内接円と交差するかどうかを確認します。交差点がある場合は、候補者を解雇します。すべてのトリプレットで見つけることができる最大のものを取ってください。
3つのサイトの等距離軌跡の計算の詳細については、私の 修士論文 の第3章を参照してください。
O(n log X)アルゴリズム。Xは必要な精度に依存します。
円の最大半径Rのバイナリ検索:
各反復で、特定の半径rに対して、各エッジEをRの「内側」にプッシュして、E 'を取得します。各エッジE 'について、半平面Hをポリゴンの「内側」にあるすべてのポイントのセットとして定義します(境界としてE'を使用)。ここで、これらすべての半平面E 'の交差を計算します。これは、O(n)時間で実行できます。交差が空でない場合は、半径を持つ円を描くとr交差点の任意の点を中心として使用すると、指定されたポリゴンの内側になります。