#include "Colors.hpp" #include #include Color elevationColor(double e, double seaLevel) { if (e < seaLevel) { // Water: deep -> shallow blue. double t = std::clamp((e + 11000.0) / (seaLevel + 11000.0), 0.0, 1.0); return Color{ (unsigned char)(10 + 20 * t), (unsigned char)(30 + 90 * t), (unsigned char)(80 + 120 * t), 255 }; } // Land: green -> brown -> white by height. double t = std::clamp(e / 9000.0, 0.0, 1.0); if (t < 0.4) { double u = t / 0.4; return Color{ (unsigned char)(60 + 80 * u), (unsigned char)(140 - 30 * u), (unsigned char)(50), 255 }; } if (t < 0.75) { double u = (t - 0.4) / 0.35; return Color{ (unsigned char)(140 - 30 * u), (unsigned char)(110 - 40 * u), (unsigned char)(50 + 10 * u), 255 }; } double u = (t - 0.75) / 0.25; return Color{ (unsigned char)(110 + 145 * u), (unsigned char)(70 + 185 * u), (unsigned char)(60 + 195 * u), 255 }; } Color plateColor(int id) { float h = std::fmod(id * 0.61803398875f, 1.0f) * 360.0f; return ColorFromHSV(h, 0.65f, 0.85f); } Color ageColor(double age, double maxAge) { double t = std::clamp(age / std::max(1.0, maxAge), 0.0, 1.0); return Color{ (unsigned char)(40 + 200 * t), (unsigned char)(40), (unsigned char)(200 - 160 * t), 255 }; } Color crustColor(bool oceanic) { return oceanic ? Color{ 30, 60, 160, 255 } // oceanic: deep blue : Color{ 160, 130, 70, 255 }; // continental: warm brown } Color lakeColor() { return Color{ 40, 200, 210, 255 }; } // bright turquoise (vs ocean blue) Color biomeColor(Biome b) { switch (b) { case Biome::Ocean: return Color{ 20, 60, 120, 255 }; // deep blue case Biome::Ice: return Color{ 235, 240, 250, 255 }; // white (polar caps / snow) case Biome::Lake: return Color{ 40, 200, 210, 255 }; // bright turquoise case Biome::Beach: return Color{ 222, 210, 150, 255 }; // pale sand case Biome::Wetland: return Color{ 70, 115, 95, 255 }; // dark teal-green (swamp/bayou) case Biome::Grassland: return Color{ 130, 185, 80, 255 }; // light green case Biome::Savanna: return Color{ 185, 180, 85, 255 }; // yellow-green case Biome::Desert: return Color{ 214, 184, 120, 255 }; // tan case Biome::Forest: return Color{ 40, 110, 50, 255 }; // dark green case Biome::Taiga: return Color{ 55, 105, 85, 255 }; // blue-green (boreal) case Biome::Tundra: return Color{ 155, 165, 150, 255 }; // pale grey-green case Biome::Hills: return Color{ 120, 135, 70, 255 }; // olive case Biome::Mountains: return Color{ 135, 125, 115, 255 }; // grey-brown } return Color{ 255, 0, 255, 255 }; // unreachable; flags an unmapped biome } const char* biomeName(Biome b) { switch (b) { case Biome::Ocean: return "Ocean"; case Biome::Ice: return "Ice cap"; case Biome::Lake: return "Lake"; case Biome::Beach: return "Beach"; case Biome::Wetland: return "Wetland"; case Biome::Grassland: return "Grassland"; case Biome::Savanna: return "Savanna"; case Biome::Desert: return "Desert"; case Biome::Forest: return "Forest"; case Biome::Taiga: return "Taiga"; case Biome::Tundra: return "Tundra"; case Biome::Hills: return "Hills"; case Biome::Mountains: return "Mountains"; } return "?"; } const char* colorModeName(ColorMode m) { switch (m) { case ColorMode::Elevation: return "Elevation"; case ColorMode::Plate: return "Plates"; case ColorMode::Age: return "Crust age"; case ColorMode::Crust: return "Crust type"; case ColorMode::Biome: return "Biome"; case ColorMode::Temperature: return "Temperature"; case ColorMode::Precip: return "Precipitation"; } return "?"; } // Temperature ramp over ~[-40, 40] C: deep blue -> cyan -> green -> yellow -> red. Color tempColor(double celsius) { double t = std::clamp((celsius + 40.0) / 80.0, 0.0, 1.0); // 0 cold .. 1 hot // 4 segments between 5 control colors. static const unsigned char key[5][3] = { { 30, 40, 130 }, // -40 C deep blue { 60, 160, 210 }, // -20 C cyan { 90, 190, 90 }, // 0 C green { 225, 200, 70 }, // +20 C yellow { 210, 70, 50 }, // +40 C red }; double s = t * 4.0; int k = std::min(3, (int)s); double f = s - k; auto L = [&](int c){ return (unsigned char)(key[k][c] + (key[k + 1][c] - key[k][c]) * f); }; return Color{ L(0), L(1), L(2), 255 }; } // Precipitation ramp over normalized [0,1]: tan (dry) -> green -> teal/blue (wet). Color precipColor(double moist01) { double t = std::clamp(moist01, 0.0, 1.0); static const unsigned char key[4][3] = { { 205, 180, 120 }, // 0.00 dry tan { 170, 185, 90 }, // 0.33 scrub { 70, 160, 90 }, // 0.66 green { 40, 120, 190 }, // 1.00 wet blue }; double s = t * 3.0; int k = std::min(2, (int)s); double f = s - k; auto L = [&](int c){ return (unsigned char)(key[k][c] + (key[k + 1][c] - key[k][c]) * f); }; return Color{ L(0), L(1), L(2), 255 }; }