現在、次のような島があります。
そして、次のように手続き的に領域に分割します。
私が探しているのはどのアルゴリズムですか?下の写真のように、一貫性のある領域を作成する方法について提案がありますか。あなたの助けに感謝します。
現在、次のような島があります。
そして、次のように手続き的に領域に分割します。
私が探しているのはどのアルゴリズムですか?下の写真のように、一貫性のある領域を作成する方法について提案がありますか。あなたの助けに感謝します。
回答:
現実の世界では、これらの州境はしばしば川のような地質学的特徴をたどっています。
島の地質をモデル化し、境界線をこれから外すのが良いアプローチでしょうか?
Red Blob Gamesには、このテーマに関する優れた記事があり、見栄えの良い結果が得られています。
彼のアプローチは、ボロノイテッセレーションの使用を含み、川をセル間の境界として定義しているようです。
彼のサイトの他の記事をチェックしてください。彼はマップ生成のテーマについて多くの記事を書いています。
ボロノイ図の2つのパスでこの問題を解決します。
最初のパスでは、島を領域に大まかに分割するために、ポイントのややまばらな分布を使用します(つまり、ポイント間の距離は比較的大きくする必要があります)(ポイント生成に関する以下のメモを参照)。次に、これらの点に基づいてボロノイ図を生成します。これにより、以下に示すように、各ポイントの周りに島が多角形の領域に分割されます。
島が地域に分割されたので、次のステップはそれらの間の境界を「粗くする」ことです。そのためには、ポイントのよりコンパクトな分布を使用してポイントの新しいレイヤーを生成し(つまり、ポイント間の距離を小さくする必要があります)、これらのポイントを使用して別のボロノイ図を作成します。次に、小さな領域ごとに、「シード」ポイントをチェックして、大きな領域に割り当てます。これにより、より大きなサブディビジョン間の境界がよりぎざぎざになります。両方のボロノイ図が適切に配置された状態の詳細を次に示します。
そして、最後の境界のみを表示している同じ領域があります:
ポイントの生成に関しては、ポアソンディスク分布を使用して、ポイントを比較的うまく均等に分布させるのが好きです。他の一般的なオプションは、同様に均等な分布を取得することです。「通常の」ランダムポイントのセットでロイドのアルゴリズムを使用します。LLoyd'sはコーディングが簡単ですが、試行錯誤を繰り返して、目的の結果を得るために必要なパスの数を判断できます。
このアプローチの潜在的な問題の1つは、最初のパスのパーティション分割で非常に小さな領域が生成される可能性があることです。最終結果でそれらが必要ない場合は、ランダムな隣接領域に単純にマージします。
私が提供したイラストはたまたまラスター画像ですが、この手法は多角形/ベクトル表現でも機能します。
MineCraftはこれをうまく行い、その世界生成アルゴリズムは徹底的に分析および文書化されています。
アルゴリズムにはさまざまな説明がありますが、そのうちの1つはhttps://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithmです。
アルゴリズムの中核は、Perlinノイズジェネレーターです。これは、バイオームの生成と同様に、標高(多かれ少なかれ、洞窟を切り開くための次のステップでも表面を変更できるため)を直接制御します。バイオームジェネレーターのようなものは、おそらくあなたがあなたのエリアを作成するために使用したいものです。
(古いバージョン)が文書化されており、基本的には、2つの異なるPerlinノイズジェネレーターを使用して動作します。変数自体(温度と降水量)は、後でゲームで実際には使用されません。たとえば、砂漠には雨はありませんが、ゲームはこれを元の降水量ではなく「砂漠」プロパティから決定します。
ランダムシードからバイオームマップを生成するためのさまざまなオンラインツールがあり、そのうちの1つがmineatlas.comです。内部的には、MineCraft自体の内部クラスを使用するJavaサーバーを使用していると思います。それらのソースコードが直接利用できるかどうかはわかりません。
たとえば、Azgaarが使用する典型的なアルゴリズム(ソースコード)。おおよそ次のようなものです:
ラスターベースのアプローチではなくベクトル形式でこれを行うことに興味がある場合は、これについてかなり前にブログ投稿を書きました。
http://blog.particracy.com/worlds-and-their-geography/
アイデアは、メッシュ(通常はボロノイベース)から始めて、十分に間隔を空けてランダムにシードされたポイントから同心円状に領域を成長させることです。