layers/craters/profiles/martin_parkes_dunstan.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "terraingen/layers/craters/profiles/martin_parkes_dunstan.h" | ||
| 2 | |||
| 3 | #include <cmath> | ||
| 4 | #include <stdexcept> | ||
| 5 | |||
| 6 | namespace terraingen { | ||
| 7 | |||
| 8 | 5211483 | double MartinParkesDunstanProfile::Height(double distance, double diameter, | |
| 9 | const CraterState& state) const { | ||
| 10 | 5211483 | const double depth = state.current.depthRatio * diameter; | |
| 11 | 5211483 | const double rim = state.current.rimHeightRatio * diameter; | |
| 12 | 5211483 | const double freshRim = state.fresh.rimHeightRatio * diameter; | |
| 13 | 5211483 | if (!(depth > 0.0 && rim >= 0.0 && rim <= freshRim)) { | |
| 14 | throw std::invalid_argument( | ||
| 15 | 3 | "Crater state needs a positive depth and 0 <= rim height <= fresh rim height"); | |
| 16 | } | ||
| 17 | 5211480 | const double radius = 0.5 * diameter; | |
| 18 | 5211480 | const double x = distance / radius - 1.0; | |
| 19 | 5211480 | if (x >= 1.0) { | |
| 20 | 13152 | return 0.0; | |
| 21 | } | ||
| 22 | 5198328 | const double k = freshRim - rim + depth; | |
| 23 | 5198328 | const double alpha = (rim - freshRim) / k; | |
| 24 | 5198328 | if (x <= alpha) { | |
| 25 | 3274831 | return (k * x + 2.0 * k) * x + freshRim; | |
| 26 | } | ||
| 27 | 1923497 | if (x <= 0.0) { | |
| 28 | 829142 | return k * (alpha + 1.0) / alpha * x * x + rim; | |
| 29 | } | ||
| 30 | 1094355 | const double ejectaScale = 0.14 * std::pow(radius, 0.74); | |
| 31 | 1094355 | const double offset = rim - ejectaScale; | |
| 32 | 1094355 | const double gradient = -ejectaScale / 8.0 - offset; | |
| 33 | 1094355 | const auto ejecta = [&](double at) { | |
| 34 | 1094355 | return ejectaScale / ((at + 1.0) * (at + 1.0) * (at + 1.0)) + offset + gradient * at; | |
| 35 | 1094355 | }; | |
| 36 | 1094355 | const double beta = std::fmin(1.0, 1.5 * (freshRim - rim) / k); | |
| 37 | 1094355 | if (x <= beta) { | |
| 38 | 520109 | const double a = (rim - ejecta(beta)) / (2.0 * beta * beta * beta); | |
| 39 | 520109 | return (a * x - 3.0 * a * beta) * x * x + rim; | |
| 40 | } | ||
| 41 | 574246 | return ejecta(x); | |
| 42 | } | ||
| 43 | |||
| 44 | } // namespace terraingen | ||
| 45 |