albedo/blast_zones.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Blast zones: the regolith a lander's descent engine scoured, brighter than around it. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/albedo/albedo.h" | ||
| 6 | #include "terraingen/util/surface.h" | ||
| 7 | |||
| 8 | #include <cstdint> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | namespace terraingen { | ||
| 12 | |||
| 13 | /// The blast zone around one lander, after Clegg et al. (2014) and Clegg-Watkins et al. (2016): | ||
| 14 | /// an elliptical zone of `area` brighter by `change` on average, brightest within about a third of | ||
| 15 | /// its radius and fading to its edge, inside a fainter halo reaching `haloReach` times as far, with | ||
| 16 | /// a darker core of `coreRadius` metres where the soil beneath the engine and the crew's tracks | ||
| 17 | /// were disturbed. Changes are relative to the undisturbed ground at 30 degrees phase. | ||
| 18 | /// | ||
| 19 | /// Measured areas: Apollo 18,725 to 53,872 m^2 (mean 28,785, thrust 45 kN), Luna 987 to 3355 m^2 | ||
| 20 | /// (mean 2100, 16 to 19 kN), Surveyor 131 to 279 m^2 (mean 215, under 0.5 kN), Chang'e-3 2530 m^2 | ||
| 21 | /// (7.5 kN). Changes: Apollo +7.5% to +12.5% (mean +10.9%), Luna +5.1% to +10.6%, Surveyor +3.4% | ||
| 22 | /// to +13.2%, Chang'e-3 +10%. Apollo dark cores: -15% to -30% within a few metres. | ||
| 23 | struct BlastZone { | ||
| 24 | 1 | double x = 0.0; ///< Surface x of the lander. | |
| 25 | 1 | double y = 0.0; ///< Surface y of the lander. | |
| 26 | 1 | double area = 28785.0; ///< Area of the zone (m^2), the Apollo mean; positive. | |
| 27 | 1 | double elongation = 1.14; ///< Long over short axis; Apollo 200 / 175, Chang'e-3 1.74. | |
| 28 | 1 | double headingDegrees = 90.0; ///< Long axis, degrees counter-clockwise from east. | |
| 29 | 1 | double change = 0.109; ///< Mean reflectance change over the zone; above -1. | |
| 30 | 1 | double haloChange = 0.04; ///< Change of the halo beyond the zone (Chang'e-3). | |
| 31 | 1 | double haloReach = 1.9; ///< Halo's reach over the zone's (Chang'e-3); at least 1. | |
| 32 | 1 | double coreRadius = 0.0; ///< Radius of the dark core (m); 0 for none. | |
| 33 | 1 | double coreChange = -0.2; ///< Change of the dark core; above -1. | |
| 34 | 1 | double raggedness = 0.15; ///< Share of the radius the edge's lobes pull in, [0, 1). | |
| 35 | 1 | std::uint32_t seed = 0; ///< Varies the edge's lobes. | |
| 36 | |||
| 37 | 1 | bool operator==(const BlastZone&) const = default; | |
| 38 | }; | ||
| 39 | |||
| 40 | /// Checks a blast zone. | ||
| 41 | /// @throws std::invalid_argument for a non-finite position, a non-positive area, an elongation or | ||
| 42 | /// halo reach below 1, a non-finite heading, changes at or below -1 or not finite, a negative core | ||
| 43 | /// radius, or a raggedness outside [0, 1). | ||
| 44 | void ValidateBlastZone(const BlastZone& zone); | ||
| 45 | |||
| 46 | /// The share of a zone's peak change it averages over its area, by the radial profile: full out | ||
| 47 | /// to 0.3 of the radius, then fading to 0 at the edge. | ||
| 48 | double BlastZoneMeanShare(); | ||
| 49 | |||
| 50 | /// Blast zones around landers, changing the albedo by the relative reflectance they give; the | ||
| 51 | /// same in any grid, tile or point. | ||
| 52 | class BlastZoneAlbedo final : public AlbedoLayer { | ||
| 53 | public: | ||
| 54 | /// @throws std::invalid_argument for a zone invalid as `ValidateBlastZone`. | ||
| 55 | explicit BlastZoneAlbedo(std::vector<BlastZone> zones, Surface surface = {}); | ||
| 56 | |||
| 57 | /// Changes the albedo at one point by the zones over it; NaN stays NaN. | ||
| 58 | void ApplyAt(AlbedoSample& value, std::size_t bands, double x, double y, | ||
| 59 | const AlbedoContext& context) const override; | ||
| 60 | |||
| 61 | /// The relative reflectance change `zone` gives (`x`, `y`). | ||
| 62 | double Change(const BlastZone& zone, double x, double y) const; | ||
| 63 | |||
| 64 | /// How far (m) from its lander `zone` changes the ground. | ||
| 65 | static double Reach(const BlastZone& zone); | ||
| 66 | |||
| 67 | /// The zones. | ||
| 68 | 1 | const std::vector<BlastZone>& Zones() const { | |
| 69 | 1 | return zones_; | |
| 70 | } | ||
| 71 | |||
| 72 | private: | ||
| 73 | std::vector<BlastZone> zones_; | ||
| 74 | Surface surface_; | ||
| 75 | }; | ||
| 76 | |||
| 77 | } // namespace terraingen | ||
| 78 |