web-dev-qa-db-ja.com

ポリゴンに同じサイズの領域を生成する

特定のポリゴンでnの同じサイズの領域を見つける擬似コードロジックを探しています。一致する領域の間または外側にスペースを入れないでください。エリアの最初の有効な一致が返されます。

入力として次のポリゴン[2,2, 3,1, 5,1, 5,4, 4,5, 2,3]を想定します。

enter image description here

...および3をパラメーターとして使用すると、有効な出力は[ [2,2, 3,2, 3,3, 4,3, 4,5, 2,3], [2,2, 3,1, 5,1, 4,2, 4,3, 3,3, 3,2], [4,5, 4,2, 5,1, 5,4] ]になります。

enter image description here

パラメータ3の別の有効な出力は[ [3,4, 3,3, 4,3, 4,2, 3,2, 3,1, 2,2, 2,3], [4,3, 4,2, 3,2, 3,1, 5,1, 5,3], [3,4, 3,3, 5,3, 5,4, 4,5] ]です。

enter image description here

エリアは同じ中心点を共有する必要がないことに注意してください。 1つ以上の領域が、ポリゴン内の他の領域の間にちょうど入る場合があります。

これは、サンプルの入力/出力の別の例です。

次のポリゴン[1,3, 1,1, 7,1, 7,2, 8,2, 8,3, 5,6, 4,6]を入力として想定します。

enter image description here

..および5をパラメーターとして使用すると、有効な出力は[ [1,3, 1,1, 3,1, 3,2, 4,3, 3,4, 3,3], [3,2, 3,1, 7,1, 7,2, 6,2, 6,3, 5,3, 5,2], [6,2, 8,2, 8,3, 6,5, 5,5, 5,4, 6,4], [1,3, 3,3, 3,4, 5,5, 6,4, 6,5, 7,5, 6,6, 5,6], [3,4, 4,3, 3,2, 5,2, 5,3, 6,3, 6,4, 5,4, 4,5] ]になります。

enter image description here

以下の仮定がなされています:

  • すべての境界線の方向は45で割り切れます

  • 整数座標はすべてのポリゴンに使用されます

  • 入力ポリゴンの整数領域は常にnで割り切れます

  • すべてのポリゴンは、convexまたはconcaveのいずれかです。

  • 解決可能、つまりnエリアは指定されたポリゴンに適切に収まることができます

8
Sergey Lukin

解決できません。実行できないことに気づくまで、いくつかの方法を試しました。

エリア4の形状を想定します。エリア4は、それぞれエリア2の2つの部分に分割する必要があります。

squares

左端の三角形と正方形は形状1の一部である必要がありますが、別の三角形が必要です。そこから取ることができる唯一の場所は右側の正方形ですが、残りは2つの領域に分割されます。

6
NiklasJ

Doc Browns(それ以外の場合は優れた)の回答に対するコメントで述べたように、正方形->三角形の分割の選択の問題があり、アルゴリズムのデバイス化が少し難しくなります。また、私の提案のいくつかが示すように、あなたはそれを連続的にする必要はありませんが、並行してそれをすることができます。

最初は、いくつかのヒューリスティックなアプローチを行いました。

ボロノイ:形状内のN点(非整数座標)を選択し、ボロノイマップを作成します。ポイントがそれらの領域に対して互いに引き付け合い、反発するようにします(引き付けが大きすぎる、反発が小さすぎる)。

大きなA/Nに役立ち、極大に陥りやすい。

Circle method:目標は、問題のある領域を削除してから、別の方法を引き続き使用することです。

内部の点(非整数)と半径rを選択します。内部から円を引いたものは、k個の切断されたサブ領域を作成します。サブリージョンのサイズがA/nの場合は、削除します。また、2 * A/nの場合は、簡単に分割して削除できるはずです。半径を少し下げて続行します(おそらくバイナリ検索を使用します)。

問題のあるポイントの増加: Doc Brownが言及する方法の使用を開始しますが、ほとんどのエッジで2つの選択肢があるため、グラフをスキップし、境界上の各領域を成長させて、新しい問題のあるポイントをできるだけ少なく作成します。可能性があります(問題のあるポイント= 1つのエッジのみを残りの形状と共有する三角形)。例えば。含める新しいネイバーを選択するときは、凸面の順に追加します(凹面=負の凸面)

リボンの成長:ほぼ凸状または凸状の領域。外部エッジ上のポイントを選択し、適切な長さになるまで単位幅のリボンが外部エッジに沿って移動するようにして、新しい切断されたポイントを作成しないようにします。必要に応じて、最後の三角形をスキップして、幅を少し大きくします。最後の領域が適切なサイズになるまで、最後のリボンが終了した場所に次のリボンをたどらせます。

ゲーム風またはオーガニック: N個の「国」を作成します。それらをランダムな場所に置きます。それらを有機的に成長させます。それらが出会うと、現在の面積が最も小さいものが最も強く、三角形に勝ちます。おそらく極大になりやすいですか?

6
NiklasJ

一般的な戦略は、ポリゴンP0(Aは総面積)からエリアA/nの最初の部分を削除し、エリアA-A/nの新しいポリゴンP1を残すことです。次に、これを繰り返してポリゴンP2、次にP3を生成し、n回繰り返した後、ソリューションが得られます。各ステップで、残りのパーツがまだ接続されたポリゴンを形成しているような新しいピースを見つけることができない可能性があることに注意してください。この場合、1つのステップに戻って別のピースを見つけるか、結果なしでアルゴリズムを停止する必要があります。 。

このようなサイズA/nのピースを作成するには、ポリゴンを「グリッドピース」に分割することから始めます。ポリゴン内のグリッドの正方形は、そのようなピースを形成します。また、ポリゴンの境界が正方形を2つに分割する、三角形の半分の正方形も形成します。 point-in-polygon test を利用して、ポリゴンのバウンディングボックス内のすべての半正方形を反復処理し、それらの中点が指定されたポリゴン内にあるかどうかをテストできます(正方形の両方の半分の場合)含まれていますが、代わりに完全な正方形を使用できます)。次に、平面 graph を作成します。ここで、各部分は頂点を定義します(「面積」または「重み」は1または1/2です)。そのグラフのエッジは、隣接する部分によって与えられます。これにより、幾何学的問題がグラフの問題になります。ここでは、総重みA/nの頂点を持つ接続されたサブグラフを探していますが、残りのグラフはまだ 接続されている です。

後者の問題は、 バックトラッキング アプローチによって解決される可能性があります。接続を解除せずにグラフから削除できる1つの頂点から始めます。必要に応じて、頂点をランダムに選択するか、すべての頂点のリストを1回ランダムにシャッフルして、次の手順で再利用できます。次に、最初の頂点に接続されている2番目の頂点を見つけてみます。これは、接続性を損なうことなく、残りのグラフから削除できます。複数の可能性がある場合は、1つをランダムに選択します。正方形を表す頂点の場合、いずれかの方法で正方形を2つの三角形に分割する(これにより、重み1/2の新しい頂点が作成される)グラフ操作を許可することもできます。これは、元のグラフからサブグラフに1つの頂点を移動するよりも少し複雑ですが、それほど難しいことではありません。

サブグラフが総重量A/nに達するか、別の頂点が見つからなくなるまで、これを繰り返します。その場合は、1つのレベルを「バックトラック」して、最初に別の頂点を試してください。

これを最適化するにはいくつかの方法があります。たとえば、グラフの高速接続テストを選択する必要があります。このサブ問題のアルゴリズムはたくさんあると思います。Googleを使用するか、 ここから開始 を使用してください。 1つの頂点が削除されたときに、接続されたグラフがまだ接続されているかどうかをすばやく確認できるアルゴリズムを探す価値があるかもしれません。

お役に立てれば。

3
Doc Brown