Mam wygenerowaną proceduralnie mapę z wykorzystaniem komórek Voronoi, z określonym poziomem morza i wiarygodną mapą wysokości.
Do tej pory z powodzeniem opisywałem niektóre cechy geograficzne: ląd, ocean, jeziora, rzeki, ujścia rzek, przecięcia, góry i biomy. Biomy obejmują tundrę, las borealny, łąki i las umiarkowany. Istnieje również kilka innych biomów, ale dla moich celów nie są one obecnie ważne.
Chciałbym teraz oznaczyć zatoki i cieśniny, ale nie wiem, jak to zrobić poprawnie. Zatoka jest zagłębionym, przybrzeżnym zbiornikiem wodnym, który bezpośrednio łączy się z oceanem.
Cieśnina to naturalnie uformowana, wąska droga wodna, która łączy dwie części oceanu. Zasadniczo tam, gdzie dwa kawałki ziemi prawie się stykają, a po obu stronach jest ocean. Nazywany także „kanałem”.
Aby określić funkcje, mogę przeglądać dowolne funkcje według typu:
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));
źródło
Odpowiedzi:
Sposób, w jaki Dragons Abound identyfikuje zatoki, polega na przejściu wzdłuż linii brzegowej i znalezieniu dwóch miejsc na linii brzegowej, w których odległość między plamami w linii prostej jest mniejsza niż odległość wzdłuż linii brzegowej między plamami. Jest to falistość linii brzegowej między dwoma punktami. Wybierając limit sinuosity i granice odległości linii między punktami, możesz zidentyfikować wąskie głębokie zatoki, szerokie płytkie zatoki itp.
Na tym zdjęciu czerwone i fioletowe kropki pokazują dwa punkty kandydujące, a zielona linia jest linią brzegową między punktami. Sinuosity to stosunek tych dwóch długości:
Alternatywnie możesz wybrać dwa punkty na wybrzeżu i utworzyć wielokąt, łącząc dwa punkty i linię brzegową między dwoma punktami (tj. Połącz zieloną linię powyżej z czerwonej kropki do fioletowej kropki). Zmierz powierzchnię tego wielokąta. Zatoka będzie miała większą powierzchnię niż zatoka bez zatoki.
Z mojego doświadczenia wynika, że kombinacja tych dwóch miar była najlepsza do wiarygodnego identyfikowania tego, co ludzie postrzegają jako zatoki.
Pamiętaj, że wykryje to także punkty. Aby znaleźć tylko zatoki, musisz sprawdzić, czy „wnętrze” zatoki zawiera wodę, a nie ląd. Szybkim i łatwym sposobem na to jest sprawdzenie punktu środkowego linii między dwoma punktami, aby sprawdzić, czy jest to woda. (Można to oszukać, ale ogólnie jest wystarczające).
Powiązanym problemem jest identyfikacja „ujścia” przęsła - tj. Najlepszy wybór dla dwóch punktów oznaczających otwór do przęsła. Zazwyczaj będziesz mieć grupę kandydatów na „usta”. Na powyższej przykładowej mapie możesz umieścić ujście tej zatoki dalej lub dalej. Ogólnie rzecz biorąc, prawdopodobnie nie ma to większego znaczenia, ale heurystyką, która działa dość dobrze, jest zminimalizowanie odległości linii prostej od ust.
Nie robiłem jeszcze cieśnin, ale moją intuicją jest sprawdzanie punktów wzdłuż linii brzegowej, aby znaleźć najbliższy punkt na innej linii brzegowej; jeśli jest poniżej określonego limitu, jest to cieśnina.
źródło
Oto ogólny pomysł z wykorzystaniem transformacji przetwarzania obrazu w celu wyizolowania interesujących funkcji:
Zastosuj wypełnienie zalewowe z komórki oceanu, aby utworzyć maskę wszystkich komórek oceanu. W zależności od konfiguracji rzek może być potrzebne dodatkowe wzniesienie lub kryterium prześwitu, aby maska oceanu nie przepływała w głąb lądu. ;)
Zastosuj lokalne wygładzanie do krawędzi tej maski, zachowując łączność / topologię bez zmian, ale wygładzając małe, hałaśliwe funkcje wybrzeża, które mogą rozpraszać uwagę. To pozwala nam skupić się na dużych zatokach nad małymi wlotami. Możesz użyć szerokości jądra filtra / liczby iteracji, aby dokładnie kontrolować skalę zachowanych funkcji.
Tutaj zastosowałem filtr mediany kilka razy. Automaty komórkowe to kolejny popularny sposób na erozję gładkich kształtów z głośnego sygnału wejściowego.
Zamień maskę w pole odległości, w którym każda komórka przechowuje swoją odległość od wygładzonej linii brzegowej.
Teraz widzimy obiecujące funkcje. W podpisanym polu odległości zarówno zatoki, jak i cieśniny ukazują się jako ostre grzbiety, a odległość spada na boki. Możemy użyć filtra wykrywania krawędzi, aby wyskoczyć z tych krawędzi:
Następnie możesz rozróżnić zatoki i cieśniny, podążając za grzbietem, aby określić jego łączność. Zatoka jest grzbietem, który biegnie w kierunku wybrzeża, stając się coraz płytszy (w odległości od lądu), aż kończy się w punkcie. Cieśnina jest grzbietem, który łączy region o dużej odległości z innym regionem o dużej odległości, przechodząc przez region o niższej odległości po drodze.
Lub innym sposobem jest przypisanie każdej wyspie identyfikatora (wyszukiwanie połączonego komponentu), a następnie, gdy tworzysz pole odległości, propaguj „najbliższy identyfikator wyspy” wzdłuż granicy odległości. Zatoka lub wlot jest wówczas grzbietem w wodzie sąsiadującym z tą samą masą lądową po obu stronach, podczas gdy kanał jest grzbietem, który oddziela wodę przylegającą do dwóch różnych mas lądowych.
Możesz ustawić minimalne i maksymalne ograniczenia odległości od brzegu lub długości grzbietu, aby kontrolować, które elementy do oznakowania, jeśli chcesz na przykład wykluczyć zbyt wąskie / szerokie cieśniny.
źródło
Zasadniczo musisz pomyśleć o tym, co dokładnie rozumiesz przez zatokę lub cieśninę i dlaczego chcesz je rozróżnić (czy to do obliczeń AI, czy do oznaczania punktów orientacyjnych, czy czegoś innego?). Zapoznaj się z kilkoma definicjami, aby znaleźć tę, która najbardziej Ci odpowiada. Następnie sformułuj warunki, aby sprawdzić komórki Voronoi. Kilka sugestii:
Zatoka
Bełt
źródło