layers/craters/profiles/complex.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief `ComplexCraterProfile`: flat floors, terraced walls and central peaks. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/layers/craters/profiles/profile.h" | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <optional> | ||
| 9 | |||
| 10 | namespace terraingen { | ||
| 11 | |||
| 12 | /// y = `coefficient` * D^`exponent` with D and y in kilometres (km^3 for volumes), as | ||
| 13 | /// morphometric relations are published. | ||
| 14 | struct KilometrePowerLaw { | ||
| 15 | 1 | double coefficient = 0.0; ///< y of a 1 km crater, in km (or km^3). | |
| 16 | 1 | double exponent = 0.0; ///< Power of the diameter. | |
| 17 | |||
| 18 | /// y in metres (m^3 with `volume`) for a crater of `diameter` metres. | ||
| 19 | double At(double diameter, bool volume = false) const; | ||
| 20 | |||
| 21 | 1 | bool operator==(const KilometrePowerLaw&) const = default; | |
| 22 | }; | ||
| 23 | |||
| 24 | /// The flat floor and central peak of complex craters on a body, from the diameter they start | ||
| 25 | /// at; depth and rim height come from the crater's state. | ||
| 26 | struct ComplexCraterShape { | ||
| 27 | double transitionDiameter = 0.0; ///< Smallest complex crater (m). | ||
| 28 | KilometrePowerLaw floorDiameter; ///< Diameter of the flat floor. | ||
| 29 | KilometrePowerLaw peakHeight; ///< Height of the central peak above the floor. | ||
| 30 | KilometrePowerLaw peakVolume; ///< Volume of the central peak (km^3), with no `peakDiameter`. | ||
| 31 | /// Diameter of the central peak's base, when known; otherwise the base follows from the peak's | ||
| 32 | /// height and `peakVolume`. | ||
| 33 | std::optional<KilometrePowerLaw> peakDiameter; | ||
| 34 | /// Largest crater the peak relations were fitted to (m); larger craters keep this size's peak | ||
| 35 | /// height and a base in proportion to the diameter. 0 applies the laws to every size. | ||
| 36 | double peakFitMaxDiameter = 0.0; | ||
| 37 | double ejectaExponent = 3.0; ///< The exterior falls off as (r / R)^-exponent. | ||
| 38 | double reachRadii = 3.0; ///< Radii from the centre where the exterior reaches zero. | ||
| 39 | |||
| 40 | bool operator==(const ComplexCraterShape&) const = default; | ||
| 41 | }; | ||
| 42 | |||
| 43 | /// Checks a complex crater shape. | ||
| 44 | /// @throws std::invalid_argument for a non-positive transition diameter, a power law with a | ||
| 45 | /// non-positive coefficient, a negative peak fit limit, a non-positive ejecta exponent, or a reach | ||
| 46 | /// of at most 1 radius. | ||
| 47 | void ValidateComplexCraterShape(const ComplexCraterShape& shape); | ||
| 48 | |||
| 49 | /// Simple craters below a transition diameter, complex ones from it: a flat floor, a concave | ||
| 50 | /// wall, a central peak lowered as the crater wears, and a power-law exterior. | ||
| 51 | class ComplexCraterProfile final : public CraterProfile { | ||
| 52 | public: | ||
| 53 | /// @param simple The profile of simple craters. | ||
| 54 | /// @throws std::invalid_argument for a null `simple` or an invalid `shape`. | ||
| 55 | ComplexCraterProfile(std::shared_ptr<const CraterProfile> simple, ComplexCraterShape shape); | ||
| 56 | |||
| 57 | double Height(double distance, double diameter, const CraterState& state) const override; | ||
| 58 | |||
| 59 | /// The larger of the simple profile's reach and `reachRadii`. | ||
| 60 | double ReachRadii() const override; | ||
| 61 | |||
| 62 | /// True from `transitionDiameter`. | ||
| 63 | 156265 | bool IsComplex(double diameter) const override { | |
| 64 | 156265 | return diameter >= shape_.transitionDiameter; | |
| 65 | } | ||
| 66 | |||
| 67 | /// The shape the profile was made with. | ||
| 68 | 100804 | const ComplexCraterShape& Shape() const { | |
| 69 | 100804 | return shape_; | |
| 70 | } | ||
| 71 | |||
| 72 | /// The profile of simple craters. | ||
| 73 | 100803 | const CraterProfile& Simple() const { | |
| 74 | 100803 | return *simple_; | |
| 75 | } | ||
| 76 | |||
| 77 | private: | ||
| 78 | std::shared_ptr<const CraterProfile> simple_; | ||
| 79 | ComplexCraterShape shape_; | ||
| 80 | }; | ||
| 81 | |||
| 82 | } // namespace terraingen | ||
| 83 |