#!/usr/bin/gawk -f # reinhard@finalmedia.de # Endlose prozedurale Welt & Animation aus mathematischen Konstanten # Public Domain BEGIN { # --- PRÄZISE KONSTANTEN MIT ERWEITERTEN NACHKOMMASTELLEN --- PHI = 1.618033988749894848204586834365; # Goldener Schnitt (Wachstum) E = 2.718281828459045235360287471352; # Eulersche Zahl (Dämpfung) PI = 3.141592653589793238462643383279; # Kreiszahl (Wellen) FEIG = 4.669201609102990671853964179714; # Feigenbaum Delta (Bruchstrukturen) GAUSS = 5.124611797498113312411252371423; # Gauß-Konstante (Skaliert, Terraintiefe) TAU = 6.283185307179586476925286766559; # 2 * PI (Periodizität) ESQ = 7.389056098930650227230427460575; # e^2 (Steilheit) if (!width) width=ENVIRON["SCREEN_WIDTH"]; if (!height) height=ENVIRON["SCREEN_HEIGHT"]; if (!width) width = 1920; if (!height) height = 1080; # Frame-Größe für die Echtzeit-Animation W = width; H = height; # Endlose Animationsschleife (frame zählt die Zeit hoch) frame = 0; while (1) { # 'f' signalisiert dem Anzeigeprogramm den Start eines neuen Frames printf "f %d\n", frame; # Die Fluggeschwindigkeit wird durch die Eulersche Zahl moduliert speed = frame * (E * 0.05); for (y = 0; y < H; y++) { # Perspektivische Transformation (Horizont bei H/2) fy = (y - H / 2.0) / (H / 2.0); if (fy <= 0) { # Himmel: Färbung basierend auf PI und FEIG for (x = 0; x < W; x++) { fx = (x - W / 2.0) / (W / 2.0); r = int(20 + (1.0 - abs(fx)) * 30); g = int(40 + (1.0 - fy) * 40); b = int(120 + (1.0 - fy) * 100); printf "p %d %d %d %d %d\n", x, y, r, g, b; } continue; } # Tiefenberechnung (3D-Distanz z im Raum) # Je näher am Horizont (fy nah an 0), desto weiter weg ist das Terrain z = 1.0 / fy; for (x = 0; x < W; x++) { fx = (x - W / 2.0) / (W / 2.0); # 3D-Weltkoordinaten berechnen # x_w schwenkt sanft hin und her (moduliert durch PHI) x_w = fx * z + sin(frame * 0.02 * PHI) * GAUSS; y_w = z + speed; # Kontinuierlicher Vorwärtsflug # --- PROZEDURALE LANDSCHAFT (FRACTAL NOISE SYNTHESE) --- # Wir schichten harmonische Wellen mit den Konstanten als Frequenzen h = 0; h += sin(x_w * PHI) * cos(y_w * E); h += sin(x_w * PI * 0.5) * cos(y_w * FEIG * 0.5) * 0.5; h += sin(x_w * TAU * 0.25) * cos(y_w * ESQ * 0.25) * 0.25; h += sin(x_w * GAUSS * 2.0) * cos(y_w * PHI * 2.0) * 0.125; # Normalisierung der Höhe auf den Bereich [-1, 1] h /= (1.0 + 0.5 + 0.25 + 0.125); # Berechne den Schnittpunkt mit dem Sichtstrahl # Wenn die Geländehöhe h größer als die Strahlhöhe ist -> Treffer terrain_height = (h + 0.2) * ESQ; # Skaliert mit e^2 # Farb- und Schattierungsberechnung (Natürlicher Look) if (h < -0.2) { # Tiefes Tal / Wasserflächen (Blau-Töne) r = int(10 + (h + 1.0) * 20); g = int(30 + (h + 1.0) * 40); b = int(150 + h * 50); } else if (h > 0.4) { # Berggipfel / Schnee (Weiß-Grau) r = g = b = int(200 + (h - 0.4) * 80); } else { # Vegetation / Hänge (Naturgrün moduliert durch FEIG) # Erzeugt organische Übergänge ohne echte Zufallszahlen slope = cos(x_w * PI) * sin(y_w * PHI); r = int(40 + slope * 15); g = int(110 + h * 100 + slope * 25); b = int(40 - h * 20); } # Atmosphärischer Dunst (Nebel in der Ferne) # Je weiter weg (höheres z), desto mehr verblasst die Farbe im Himmelsblau fog = 1.0 - exp(-z / (GAUSS * 4.0)); r = int(r * (1.0 - fog) + fog * 40); g = int(g * (1.0 - fog) + fog * 60); b = int(b * (1.0 - fog) + fog * 160); # RGB-Kompression if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; printf "p %d %d %d %d %d\n", x, y, r, g, b; } } frame++; # Optionaler Flush für flüssiges Streaming im Terminal-Pipes fflush(); } } function abs(v) { return (v < 0) ? -v : v; }