TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
9 / 9
100.0%
Branches:
2 / 4
50.0%
Functions:
4 / 4, 1 excl
100.0%

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
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
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