手続き的に生成されたマップで湾と海峡をどのように決定できますか?


40

ボロノイセルを使用して、定義済みの海面と信頼できる高さマップを使用して、手順で生成されたマップを取得しました。

現在

これまでのところ、土地、海、湖、川、河口、合流点、山、バイオームなどの特定の地理的特徴のラベル付けに成功しています。バイオームにはツンドラ、寒帯林、草原、温帯林が含まれます。他にもいくつかのバイオームがありますが、私の目的にとっては今のところ重要ではありません。

次に湾と海峡にラベルを付けたいのですが、これを適切に行う方法に迷っています。湾とは、海に直接つながる窪んだ沿岸の水域です。

海峡は、海の2つの部分を結ぶ自然に形成された狭い水路です。基本的に、2つの土地がほとんど接触しており、両側に海があります。「チャネル」とも呼ばれます。

機能を決定するには、次のようにタイプ別に機能をループします。

for each (var feature:Object in geography.getFeaturesByType(Geography.LAND))
  // loop through lands
  for each (var cell:Cell in feature.cells)
  // loop through cells
    for each (var neighbor:Cell in cell.neighbors)
    // loop through a cell's neighbors
      trace(neighbor.hasFeatureType(Geography.LAND));

8
ベイジアン分類器をお勧めします。
蓄積

1
@Acccumulationこれは「ベイ」のしゃれですか、これは深刻な提案ですか?後者の場合、これについて適切な答えを書く必要があります。
フィリップ

私は彼が冗談を言っていることを99%確信しているようです。
オーリンカークランド

回答:


29

ドラゴンズアバウンドが湾を識別する方法は、海岸線に沿って歩き、スポット間の直線距離がスポット間の海岸線に沿った距離よりも小さい海岸線上の2つのスポットを見つけることです。これは、2つの地点間の海岸線の湾曲です。湾曲限界とスポット間の直線距離の制限を選択することにより、狭い深い湾、広い浅い湾などを識別できます。

この図では、赤と紫の点が2つの候補点を示し、緑の線が点間の海岸線です。湾曲度は、これら2つの長さの比です。

湾の例

または、海岸の2つのポイントを選択し、2つのポイントと2つのポイント間の海岸線を接続してポリゴンを作成します(つまり、上の緑の線を赤の点から紫の点に接続します)。このポリゴンの面積を測定します。ベイは、非ベイよりも広い面積を持ちます。

私の経験では、これらの2つの手段の組み合わせは、人々が湾と見なすものを確実に識別するのに最適でした。

これもポイントを検出することに注意してください。湾のみを見つけるには、湾の「内側」に陸地ではなく水が含まれていることを確認する必要があります。これをすばやく簡単に行うには、2点間の線の中点をチェックして、水かどうかを確認します。(これはだまされる可能性がありますが、通常は十分です。)

関連する問題は、湾の「口」を特定することです。つまり、湾の開口部をマークする2つのポイントの最適な選択です。通常、「口」の候補がたくさんあります。上記のマップ例では、その湾の口をさらに内側または外側に置くことができます。一般的に言って、それはおそらくあまり重要ではありませんが、合理的にうまく機能する1つのヒューリスティックは、口を通る直線距離を最小にすることです。

私はまだ海峡を行っていませんが、私の直感は、海岸線に沿ってポイントをチェックし、他の海岸線で最も近いポイントを見つけることです。それが設定された制限の下にある場合、それは海峡です。


3
ドラゴンズアバウンドに必要な答えがあることを知っていたはずです。
オーリンカークランド

48

以下に、画像処理変換を使用して関心のある機能を分離する大まかなアイデアを示します。

  1. 海洋セルから塗りつぶしを適用して、すべての海洋セルのマスクを作成します。川の設定方法によっては、海面が内陸に流れないようにするために、追加の標高またはクリアランス基準が必要になる場合があります。;)

    オーシャンマスク

  2. このマスクのエッジにローカルスムージングを適用して、接続性/トポロジを同じに保ちながら、気を散らす可能性のある小さなノイズの多い海岸線フィーチャをスムージングします。これにより、小さな入り江の上の大きな湾に集中できます。フィルタカーネルの幅/反復回数を使用して、保持するフィーチャのスケールを細かく制御できます。

    ここでは、メディアンフィルターを数回適用しました。セルオートマトンは、ノイズの多い入力から滑らかな形状を侵食する別の一般的な方法です。

    滑らかな海岸線

  3. マスクを距離フィールドに変えます。各フィールドには、平滑化された海岸線からの距離が格納されます。

    距離フィールド

現在、有望な機能のハイライトがいくつか表示されています。符号付きの距離フィールドでは、湾と海峡の両方が鋭い尾根として表示され、距離は両側に落ちます。エッジ検出フィルターを使用して、これらのリッジをポップアウトできます。

ハイライトされた尾根

その後、尾根に沿って接続性を判断することで、湾と海峡を区別できます。湾は海岸に向かって走る尾根であり、ある地点で終わるまで浅くなります(陸からの距離で)。海峡は、高距離地域を別の高距離地域に接続する尾根で、途中で低距離地域を通過します。

または、別の方法として、各島にID(接続コンポーネント検索)を割り当て、距離フィールドを作成するときに、距離フロンティアとともに「最も近い島ID」を伝達します。湾または入り江は両側の同じ陸地に隣接する水の尾根であり、チャンネルは2つの異なる陸地に隣接する水を分離する尾根です。

たとえば、極端に狭い/広い海峡を除外する必要がある場合、最小および最大の海岸までの距離または尾根の長さの制約を設定して、ラベルを付けるフィーチャを制御できます。


9
これは本当にクールに見え、セル構造を直接使用してグラフィカルな表現ではなくさまざまなステップを適用することで、おそらくかなり高速化できます!
クエンティン

7
第二のアプローチ(それぞれ異なる大陸にIDを割り当て、それが水の本体の両側で同じ陸地だか否かに基づいて区別する)を行うための最も簡単な事のように思える..
モンティハーダー

とにかく「ランドマスID」は、島の名前を生成するためにマップのラベル付けでも必要になるため、良いアイデアです。
MSalters

6

基本的には、湾または海峡によって正確に何を意味するのか、そしてなぜそれらを区別したいのかを考える必要があります(AI計算のためか、ランドマークにラベルを付けるためか、他の何かのために?)。いくつかの定義を試して、自分に最適な定義を見つけてください。次に、ボロノイセルをチェックする条件を策定します。いくつかの提案:

  • 他の単一の海洋セルにのみ接続する海洋セル
  • または:すべての海洋セルが互いに隣り合っている、海洋セルよりも多くの土地に接続する海洋セル
  • OR:上記と同じですが、境界線の長さに基づく基準を使用します(たとえば、水辺の2倍の土地)

海峡

  • 隣接していないちょうど2つの海洋セルに接続する海洋セル
  • OR:同じ陸地に属さない2つの陸地セルに接続する海洋セル(どの陸地セルが最初に接続されているかを確認し、各陸地にIDを割り当てる必要があります)
  • または:国境付近で行進し、土地/水と水/土地の移行をカウントします。それぞれ少なくとも2つ必要です。
  • 方法とカテゴリの処理内容に応じて、湾につながる海峡を削除するか、代わりに湾としてラベルを付けることができます。

2
海峡が湾につながると、これら2つは一緒にフィヨルドとしてラベル付けされる場合があります。
フィリップ

1
セルがベイ/海峡のサイズに比べて小さい場合は、これを伝搬して、すぐ隣の隣のセルを超えてセルを見る必要があります。
DMGregory

はい、スケーリングは少し問題であり、物事を定義し、「セル」を宣言する方法に影響します。カナダの地図を検討し、ハドソン湾、ジェームズ湾、セントローレンス湾、ファンディ湾を比較します。これらのルールを確実に適用して、目的の関連名を取得するにはどうすればよいですか?-ニューファンドランドとノバスコシアの間に「まっすぐな」ものはありますか?
17:23のTheLuckless
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.