Ich möchte fraktale Landschaften generieren und die Möglichkeiten nutzen, die mit LaTeX und Co. verfügbar sind.

Ansatz:

  • Berechnung der Landschaft mit Lua nach dem Diamond-square Algorithmus (siehe auch englischsprachige Beschreibung)
  • Ausgabe mit pgfplots, denn hier habe ich vielfältige Darstellungsmöglichkeiten
  • Surface plot mit mesh
  • Colormap zum Einfärben verwenden: blau für unterhalb des Meeresspiegels, grün für Berge, weiß für Schnee, Farbverlauf je nach Höhe

Ich werde ein komplettes Dokument als Antwort posten, das obiges umsetzt. Hat jemand dazu Verbesserungsvorschläge?

Weitere Herausforderungen:

  • Abgeschnitten auf Meeresspiegelhöhe durch blaue Ebene, vllt. durchsichtig mit opacity damit man die Tiefe dennoch wahrnimmt
  • Der Insel-Ansatz könnte gut aussehen: initialisieren auf Meeresspiegelhöhe des ganzen Randes, so müsste sich eine Insel erheben können, weniger Probleme mit dem Rand
  • Größere Matrix, hier habe ich 128, bei 256 erhalte ich Fehler. Es sollten Zweierpotenzen sein, algorithmusbedingt.

Wer experimentiert, z.B. nur den 3D Viewpoint ändert, kann den seed-Wert zum Initialisieren des Zufallsgenerators beibehalten, ansonsten variieren, bis etwas Schönes herauskommt.

gefragt 29 Jun '14, 18:13

stefan's gravatar image

stefan ♦♦
18.4k163148
Akzeptiert-Rate: 49%


Diese Lösung verwendet den Diamond-square-Algorithmus in einer Implementierung von Marc Lepage. Den Lua-Code kann man natürlich auch auslagern, das ist sogar empfehlenswert. Hier belasse ich ihn der Handhabbarkeit halber im Dokument.

  • Berechnung mit Lua
  • Ausgabe als pgfplots Surface-Plot mit Färbung (Meer, Berge, Schnee) in colormap, view für Ansicht eingestellt

Zum Variieren den seed-Wert ändern, das ist der erste Parameter beim Aufruf der Terrain-Funktion. Festhalten, wenn man nur view ändern möchte. shader=interp würde die Farben interpolieren, es sieht aber auch nicht perfekt aus.

Die Berechnung dauert lange, zum Testen besser kleinere Werte für Matrix-Dimension und mesh rows (Dimension+1) wählen.

Open in writeLaTeX
Code, hier editierbar zum Übersetzen:
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepackage{luacode}
\begin{luacode*}
function terrain(seed,dimension,options)
-- inner functions come from the Heightmap module
-- Module Copyright (C) 2011 Marc Lepage
local max, random = math.max, math.random
-- Find power of two sufficient for size
local function pot(size)
local pot = 2
while true do
if size <= pot then return pot end
pot = 2*pot
end
end
-- Create a table with 0 to n zero values
local function tcreate(n)
local t = {}
for i = 0, n do t[i] = 0 end
return t
end
-- Square step
-- Sets map[x][y] from square of radius d using height function f
local function square(map, x, y, d, f)
local sum, num = 0, 0
if 0 <= x-d then
if 0 <= y-d then sum, num = sum + map[x-d][y-d], num + 1 end
if y+d <= map.h then sum, num = sum + map[x-d][y+d], num + 1 end
end
if x+d <= map.w then
if 0 <= y-d then sum, num = sum + map[x+d][y-d], num + 1 end
if y+d <= map.h then sum, num = sum + map[x+d][y+d], num + 1 end
end
map[x][y] = f(map, x, y, d, sum/num)
end
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fraktale Landschaft

Mit shader=interp:

Fraktale Landschaft

seed=10, view={10}{55}

Fraktale Landschaft

Weitere Ideen und Schwierigkeiten stehen ganz oben am Ende der Frage. Verbesserungen und Idee sind sehr willkommen!

Permanenter link

beantwortet 29 Jun '14, 18:28

stefan's gravatar image

stefan ♦♦
18.4k163148
Akzeptiert-Rate: 49%

bearbeitet 29 Jun '14, 18:46

1

Die Farbeinstellungen (color(4cm)=(green!60!white);, color(4cm)=(white!95!black); usw.) sollen ansteigenden Werten sein!

(29 Jun '17, 06:34) Pathe

@Pathe: Bitte auf keinen Fall Blockcode-Markdown in Kommentaren verwenden! Das zerstört leider noch immer die Kommentarfunktion und manchmal die ganze Seite!

(29 Jun '17, 12:48) saputello

@Pathe: In LuaTeX 0.85 wurde pdfpagewidth und diverse andere Primitive, die aus pdfTeX stammen umbenannt. Offenbar sind nicht alle bei Dir installierten Pakete auf einem entsprechend aktuellen Stand. Verwende notfalls das Paket luatex85.

(29 Jun '17, 12:58) saputello

@saputello Ich habe die Kommentar-Frage von @Pathe in eine separate Frage umgewandelt. Dass es schon eine ähnliche Frage gab, sah ich nicht. Es ist auch nicht ganz ein Duplikat, denn statt KOMA-Klasse ist es hier standalone, und es ist eine anders lautende Fehlermeldung. Nur die Lösung ist gleich, wie Du schriebst, luatex85 zu laden.

(29 Jun '17, 13:18) stefan ♦♦

@Pathe Ja, man könnte z.B. mit color(5cm)=... fortsetzen. Mein Augenmerk lag vor allem auf der Kombination pgfplots und Lua zur Darstellung von errechneten Grafiken, nicht ganz auf Farben. :-)

(29 Jun '17, 13:21) stefan ♦♦

Dies hier ist ein Zusatz zu der exzellenten Antwort von Stefan: es verwendet neue Moeglichkeiten von colormaps, was bei Landschaften nicht uninteressant ist:

Öffne in Overleaf
Code, hier editierbar zum Übersetzen:
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\usepackage{luacode}
\begin{luacode*}
function terrain(seed,dimension,options)
-- inner functions come from the Heightmap module
-- Module Copyright (C) 2011 Marc Lepage
local max, random = math.max, math.random
-- Find power of two sufficient for size
local function pot(size)
local pot = 2
while true do
if size <= pot then return pot end
pot = 2*pot
end
end
-- Create a table with 0 to n zero values
local function tcreate(n)
local t = {}
for i = 0, n do t[i] = 0 end
return t
end
-- Square step
-- Sets map[x][y] from square of radius d using height function f
local function square(map, x, y, d, f)
local sum, num = 0, 0
if 0 <= x-d then
if 0 <= y-d then sum, num = sum + map[x-d][y-d], num + 1 end
if y+d <= map.h then sum, num = sum + map[x-d][y+d], num + 1 end
end
if x+d <= map.w then
if 0 <= y-d then sum, num = sum + map[x+d][y-d], num + 1 end
if y+d <= map.h then sum, num = sum + map[x+d][y+d], num + 1 end
end
map[x][y] = f(map, x, y, d, sum/num)
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

alt text

Die LUA implementierung ist 100% identisch; ich habe lediglich eine besondere colormap aus dem pgfplots manual (aus der Dokumentation des keys of colormap/target pos max ) eingefuegt und eingebunden. Das besondere hier ist, dass ich die colormap nicht im context eines normalen contour plots verwende (bei dem eine Zuordnung zwischen der Z koordinate und der Farbe wichtig ist), sondern einfach dem shader sage, dass er die resultierende colormap nehmen soll. Die colormap wiederum ist schon ziemlich komplex und auch nicht leicht zu durchschauen:

  • ich definiere zwei colormaps whiteblue fuer das wasser sowie gb fuer das land.
  • Ich baue die final colormap CM als konkatenation zweier of colormap klauseln.
  • Die erste of colormap klausel sampled eine Reihe von Datenpunkten aus whiteblue, naemlich genau an den spezifierten positionen. Damit bekommt man eine asymmetrische verteilung der verschiedenen blautoene hin. Die zahlen sind aus dem manual abgekupfert, weil es dort schick aussieht. Die absoluten Werte spielen eigentlich keine Rolle; wichtig ist nur der Abstand zwischen den Zahlen (bei einem contour plot waeren auch die absoluten Zahlen wichtig -- aber nicht hier).
  • Die zweite of colormap klausel sampled eine Reihe von Datenpunkten aus gb, nur ein kleines bisschen anders verteilt.
Permanenter link

beantwortet 24 Dez '17, 12:20

cfeuersaenger's gravatar image

cfeuersaenger
3.7k23
Akzeptiert-Rate: 34%

Deine Antwort
[Vorschau ausblenden]

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Frage-Themen:

×298
×28
×5

gestellte Frage: 29 Jun '14, 18:13

Frage wurde gesehen: 16,262 Mal

zuletzt geändert: 24 Dez '17, 12:20

Willkommen, erstes Mal hier? Schau mal unter FAQ!

×