diff options
| author | godosa <godosa@godosa.eu> | 2026-10-06 23:52:03 +0200 |
|---|---|---|
| committer | godosa <godosa@godosa.eu> | 2026-10-06 23:52:03 +0200 |
| commit | 346b1c5195bffc71ceaa9262453e3c189656400b (patch) | |
| tree | 01ac0d31e2724cd6abcc689a5a228e2cbea2f6cf /mapgen/zones.py | |
| download | worldgen-346b1c5195bffc71ceaa9262453e3c189656400b.tar.gz worldgen-346b1c5195bffc71ceaa9262453e3c189656400b.zip | |
worldgen: initial public history
Diffstat (limited to 'mapgen/zones.py')
| -rw-r--r-- | mapgen/zones.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/mapgen/zones.py b/mapgen/zones.py new file mode 100644 index 0000000..46386f7 --- /dev/null +++ b/mapgen/zones.py @@ -0,0 +1,38 @@ +"""Config O₂ / low-gravity zones: smooth, noise-warped discs in mask units +(O₂ ×(1 + 0.5 v), gravity ×(1 + 0.7 v)), added to the painted masks in the `sketch` stage. Very gradual: at most +≈ 1.9 · |effect| / radius per km (≤ 0.23 O₂ points and ≤ 0.014 g per 30 km for the configured zones).""" +from __future__ import annotations + +import numpy as np + +from .noise import fbm, name_seed +from .sphere import gc_dist_km, latlon_to_xyz + +WARP = 0.2 # outline wobble: distances stretched or shrunk by up to 20 % (low-frequency noise) +WARP_FREQ = 1.0 + + +def smootherstep(t): + t = np.clip(t, 0.0, 1.0) + return t * t * t * (t * (6.0 * t - 15.0) + 10.0) + + +def contribution(xyz, zone: dict, seed: int, radius_km: float): + """v · (1 − smootherstep(d′ / r)), d′ = d · (1 + WARP · warp): v at the centre, 0 beyond r / (1 − WARP).""" + xyz = np.asarray(xyz, dtype=np.float64) + d = gc_dist_km(xyz, latlon_to_xyz(*zone["center"]), radius_km) + r = float(zone["radius_km"]) + out = np.zeros(len(xyz)) + near = d < r / (1.0 - WARP) + if near.any(): + w = np.clip(2.0 * fbm(xyz[near], name_seed(seed, zone["name"]), 3, WARP_FREQ), -1.0, 1.0) + out[near] = zone["v"] * (1.0 - smootherstep(d[near] * (1.0 + WARP * w) / r)) + return out + + +def masks(xyz, zones: list, seed: int, radius_km: float): + """(m_o2, m_gravity): the config zones summed (the caller adds the painted masks and clips to [−1, 1]).""" + m = {"o2": np.zeros(len(xyz)), "gravity": np.zeros(len(xyz))} + for z in zones: + m[z["field"]] += contribution(xyz, z, seed, radius_km) + return m["o2"], m["gravity"] |
