Barrier Island Generation

Die Dezember-Nachrichten über den Hurrikan Florenz bezogen sich oft auf externe Schwärme - eine Reihe von Barriereinseln vor der Küste von North Carolina:


Barriereinseln sind flache oder blockige Sandflecken, die von Wellen gebildet werden und parallel zur Küste des Festlandes surfen. Sie haben oft die Form langer Ketten, die sich über mehrere zehn Kilometer erstrecken können. Die Barriereinseln sind normalerweise durch kleine Gezeitenkanäle getrennt und können Lagunen zwischen den Inseln und dem Festland bilden.

Laut Wikipedia können Barriereinseln bis zu 15% der Küste bedecken, sodass Sie erwarten können, sie auf den meisten Fantasy-Karten zu sehen, aber tatsächlich sind sie ziemlich selten. Und aufgrund der Art des Rauschens treten sie fast nie auf prozedural generierten Karten auf, die Rauschen verwenden, um Gelände zu erstellen.

Um zu verstehen, warum dies so ist, werfen wir einen Blick auf die Vanillekarte der Insel:


Tatsächlich handelt es sich um einen Kreis, der durch eine geringe Menge an niederfrequentem Rauschen verzerrt ist, um eine Kreisform zu teilen. Versuchen wir nun, mit Lärm die Küste zu durchbrechen und Küsteninseln zu bilden. Hier ist dieselbe Insel mit dem Zusatz von niederfrequentem Rauschen:


Es hat Buchten und Umhänge. Die Reliefelemente sind ziemlich groß, weil ich niederfrequentes Rauschen verwendet habe, das sich langsam ändert. Der Lärm ist jedoch nicht stark genug, um Inseln zu erzeugen. Lassen Sie es uns ein bisschen schieben:


Jetzt haben wir mehrere Inseln geschaffen, aber es handelt sich im Wesentlichen um kreisförmige Flecken, die sich nicht unbedingt entlang der Küste erstrecken. Sie können hochfrequentes Rauschen hinzufügen:


Dies kann uns sehr zerbrochene Küsten und kleine Inseln entlang der Küste geben, aber nichts, was einer Barriereinsel ähnelt.

Der einzige Grund dafür ist, dass das Rauschen in x und y nicht übereinstimmt. Obwohl das Rauschen im Allgemeinen nicht zufällig ist, sind die Formen, die es erzeugt, zufällig:


Für einige Dinge ist dies gut, aber es ist nicht geeignet, eine bestimmte Form zu erstellen, zum Beispiel Inseln entlang der Küste.

Wie in anderen Fällen war es beim Generieren einer bestimmten Form oder eines bestimmten Bereichs erforderlich, eine Maske mit der erforderlichen Form zu erstellen und dann das Rauschen in der Maske zu verwenden. (Sie können auch Rauschen verwenden, um die Maske zu verzerren und ihr eine natürlichere Form zu geben.) Barriereinseln sind in der Tat lange, dünne Bereiche, die von der Küste versetzt sind. Erstellen wir also eine Maske dieser Form.

Zunächst legen wir den Teil der Küste fest, an dem sich die Barriereinsel befindet. Dies kann durch Auswahl eines zufälligen Punkts an der Küste und eines zweiten unteren Punkts erfolgen, die in der Abbildung mit einer roten Linie in der oberen rechten Ecke markiert sind:


Um eine Barriereinsel zu erstellen, kann ich einfach eine gerade Linie zwischen diesen beiden Punkten nehmen und sie ein wenig nach außen ins Wasser projizieren. Dies gibt mir eine sehr gerade und unnatürlich aussehende Insel, aber Sie können ihre Form verzerren, um sie zu verbergen. Das eigentliche Problem ist, dass die Insel nicht der Küste folgt. Es wird wahrscheinlich für die meisten direkten Abschnitte der Küste normal aussehen, aber es wird an gewundenen Küsten seltsam erscheinen. Es ist besser, die Küste nachzubilden und sie zur Grundlage für die Form der Insel zu machen.

Dazu muss ich eine Kopie der Küste erstellen und sie dann senkrecht zur Küste in den Ozean projizieren. Ich habe bereits ein Verfahren zum Berechnen von Senkrechten (Normalen) zu unterbrochenen Linien, da ich handgeschriebene Linien realisiert habe und meine Küsten immer in die gleiche Richtung verlaufen. Es ist also ziemlich einfach:


Oder es scheint einfach. Mal sehen, was passiert, wenn ich die Küste etwas weiter nach außen projiziere (um die andere Seite der Inselmaske zu erstellen) auf den weniger glatten Teil der Küste:


Zwei Segmente der projizierten Linie schneiden sich und erzeugen eine erschreckende „Acht“ auf dem Polygon. Dies ist das sogenannte Parallelkurvenproblem . Wir können die Küste nicht nur in eine gewisse Entfernung verschieben, sondern müssen auch die Probleme lösen, die sich aus den scharfen Innen- und Außenecken ergeben.

Ich suchte nach Javascript-Code, um dieses Problem zu lösen, aber das einzige gefundene Beispiel ( von hier ) war ein erstaunlicher Absturz, selbst bei relativ einfachen Beispielen. Also habe ich meine eigenen geschrieben. Im Allgemeinen besteht die Lösung darin, jeden Punkt entlang der Normalen zu verschieben, dann aber zu prüfen, ob der neue Punkt eine Linie erstellt, die eine der vorhandenen Linien schneidet. Wenn ja, dann schneiden wir die Schleife ab und fügen eine neue Linie ein, die aus dem Schnittpunkt und dem neuen Punkt besteht. In den von mir getesteten Testfällen funktionierte dieses System recht gut für meine Anforderungen.

Jetzt kann ich einfache Masken (keine Schleifen) für die Inseln erstellen:


Das ist zu gleichmäßig, also werde ich die Konturen verzerren:


Die Konturen können an einigen Stellen die Küste berühren, dies ist jedoch normal und wird häufig auf Barriereinseln gefunden.

Der nächste Schritt besteht darin, die Kontur mit Land zu füllen. Bevor ich dies tue, möchte ich die Inseln verlängern und die Logik hinzufügen, sich kreuzende Inseln zu vermeiden, wenn mehrere Barriereinseln an derselben Küste erstellt werden.


Versuchen wir nun, etwas Land hinzuzufügen. Um dies zu tun, werde ich die Höhe eines beliebigen Landstandorts (bei dem es sich um Delaunay-Dreiecke handelt) über den Meeresspiegel erhöhen:


Es gibt einige bemerkenswerte Aspekte. Erstens gibt es in der oberen linken Ecke eine ziemlich erfolgreiche Barriereinsel. Die Insel scheint die Deponie jedoch nicht gut zu füllen. Viele Landdreiecke sind aufgrund des Vorhandenseins ihrer Zentren innerhalb des Polygons eingeschaltet. Dies fügt der Form der Insel Zufälligkeit hinzu. Zweitens kann man feststellen, dass die beiden anderen Inseln so nah an der Küste lagen, dass sie einfach mit ihr verschmolzen. Da ich hier Inseln erstellen möchte, muss dies nicht zu oft vorkommen. Daher werde ich die Generation so einrichten, dass ein größerer Wasserspalt zwischen der Küste und der Insel entsteht. (Später werde ich einen Scheck hinzufügen, um dies zu verhindern.)


Eines der schönen Dinge an den unregelmäßigen Dreiecken des Landes ist, dass sie auf natürliche Weise Gezeitenkanäle bilden, die typisch für Barriereinseln sind. Das Schlechte an ihnen ist, dass sie normalerweise Fleckeninseln bilden, die wie verzerrte Perlen an einer Schnur aussehen. Sie sind Barriereinseln nicht sehr ähnlich, und wenn Sie viele einzelne Dreiecke nehmen, sehen sie sehr unnatürlich aus.

Wenn ich die Breite der Inseln vergrößere, verschwinden beide Effekte und ich bekomme mehr natürliche Inseln, aber ohne Gezeitenkanäle:


Aber ich würde gerne lernen, wie man sehr schmale Inseln erzeugt. Ein anderer Ansatz besteht darin, die Anzahl der Standorte auf der Welt (signifikant) zu erhöhen, um die Auflösung zu erhöhen:


So können wir beeindruckend dünne und detaillierte Inseln erhalten, aber dies erhöht die Zeit und den Speicher, die zum Erstellen einer Karte erforderlich sind, erheblich.

Bei beiden Methoden besteht eine gute Chance, dass einige Teile der Insel sehr uneben sind:


Dies geschieht, weil der Pfad die beiden Seiten (und manchmal alle drei Seiten) der zugrunde liegenden Delaunay-Dreiecke schneidet. Dies ist ein inhärentes Problem bei der Verwendung der Delaunay-Triangulation bei der Kartengenerierung, aber aus irgendeinem Grund wird es selten diskutiert! Dies passiert in meinem Spiel an den Küsten nicht sehr oft, da ich absichtlich eine Glättungsstufe hinzugefügt habe, um die Anzahl solcher Fälle zu verringern, aber diese Stufe hat die Tendenz, schmale Inseln zu zerstören. Eine mögliche Lösung besteht darin, etwas breitere Inseln zu erstellen und Anti-Aliasing zu verwenden. Bei korrekter Einrichtung können Sie dünnere Inseln ohne viele Dreiecksartefakte erhalten:


Bei diesem Ansatz gibt es jedoch immer noch Einschränkungen, wie eng die Inseln sein können. Darüber hinaus bedeutet dies, dass wir niemals wirklich fraktale Küsten bekommen werden.

Manchmal führt der Glättungsalgorithmus dazu, dass die lange Barriereinsel in mehrere kleine aufgeteilt wird (wie in der unteren linken Ecke des obigen Bildes), aber es wäre praktisch, eine Option zu haben, mit der Sie dies zwangsweise tun können:


Das einzige, was noch übrig ist, ist, den Inselnamen zu geben und sie zu kartieren. Der einzige subtile Aspekt hier ist, dass ich nicht allen Inseln in der Kette der Barriereinseln Namen geben möchte. In realen Ketten von Barriereinseln haben einzelne Inseln oft Namen, was zu Chaos auf der Karte führt:


Daher berücksichtige ich beim Erstellen einer Barriereinsel den gesamten Bogen und füge ihm einen Namen hinzu, auch wenn die Generation den Bogen dadurch in mehrere Inseln aufteilt:


Normalerweise werden Barriereinseln als "Banks" oder "Shafts" (Bars) bezeichnet, daher werden diese Wörter in Variantennamen gefunden.

Dieses Beispiel zeigt ein potenzielles Problem mit Barriereinseln:


Hier wurde die Barriereinsel innerhalb der Bucht angelegt. Dies ist unlogisch (führt außerdem zur Überschneidung von Namen). Um dies zu vermeiden, kann ich meine Buchtenerkennungslogik verwenden und diese Abschnitte der Küste überspringen. Es gibt wahrscheinlich keinen Schutz vor dem Narren in dieser Methode, aber es funktioniert gut für diese Karte:

Source: https://habr.com/ru/post/de439198/


All Articles