materials/materials.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Material maps of a terrain: the share of soil, sand, dust, bedrock and rock at each | ||
| 3 | /// point, and the Hapke photometry they mix to. | ||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "terraingen/layers/exposure.h" | ||
| 7 | #include "terraingen/layers/material.h" | ||
| 8 | #include "terraingen/pipeline/terrain.h" | ||
| 9 | #include "terraingen/raster/grid.h" | ||
| 10 | #include "terraingen/raster/raster.h" | ||
| 11 | |||
| 12 | #include <array> | ||
| 13 | #include <cstdint> | ||
| 14 | #include <optional> | ||
| 15 | #include <vector> | ||
| 16 | |||
| 17 | namespace terraingen { | ||
| 18 | |||
| 19 | /// How a terrain's material map is made from its shape and layers. | ||
| 20 | struct MaterialOptions { | ||
| 21 | /// Bedrock where the bare ground, beneath the first layer that lays a material, is bare | ||
| 22 | /// (`ExposureField`); none for no bedrock. | ||
| 23 | 2 | std::optional<ExposureParams> exposure{ExposureParams{}}; | |
| 24 | 2 | double dustCover = 0.0; ///< About the share of the surface under dust patches, in [0, 1). | |
| 25 | 2 | double dustPatch = 50.0; ///< Typical width of a dust patch (m). | |
| 26 | 2 | std::uint32_t seed = 0; ///< Varies the dust patches. | |
| 27 | |||
| 28 | 2 | bool operator==(const MaterialOptions&) const = default; | |
| 29 | }; | ||
| 30 | |||
| 31 | /// Checks material options. | ||
| 32 | /// @throws std::invalid_argument for a dust cover outside [0, 1), a dust patch that is not | ||
| 33 | /// positive and finite, or invalid exposure thresholds. | ||
| 34 | void ValidateMaterialOptions(const MaterialOptions& options); | ||
| 35 | |||
| 36 | /// The material shares of `terrain` at world (x, y): soil, then bedrock where the ground beneath | ||
| 37 | /// the first `MaterialSource` layer is bare, then dust in patches, then each `MaterialSource` | ||
| 38 | /// layer's cover in layer order, each read on the ground beneath it. | ||
| 39 | /// @param spacing Sample spacing in metres; positive. | ||
| 40 | /// @throws std::invalid_argument as `ValidateMaterialOptions` or `ValidateTerrain`. | ||
| 41 | MaterialShares MaterialsAt(const Terrain& terrain, const MaterialOptions& options, double x, | ||
| 42 | double y, double spacing); | ||
| 43 | |||
| 44 | /// One raster per `MaterialClass` over `grid`, each cell `MaterialsAt` its centre at the grid's | ||
| 45 | /// spacing (or `evaluation.spacing` where coarser). | ||
| 46 | /// @throws std::invalid_argument as `MaterialsAt`. | ||
| 47 | std::vector<Raster<float>> EvaluateMaterials(const Terrain& terrain, const MaterialOptions& options, | ||
| 48 | const RasterGrid& grid, | ||
| 49 | const EvaluationOptions& evaluation = {}); | ||
| 50 | |||
| 51 | /// The Hapke (1993) parameters of a surface, as fitted to Pancam photometry. | ||
| 52 | struct HapkeParameters { | ||
| 53 | 3 | double albedo = 0.0; ///< Single-scattering albedo w, in [0, 1]. | |
| 54 | 3 | double b = 0.0; ///< Two-term Henyey-Greenstein asymmetry b, in [0, 1]. | |
| 55 | 3 | double c = 0.0; ///< Two-term Henyey-Greenstein backscatter fraction c, in [0, 1]. | |
| 56 | 3 | double roughness = 0.0; ///< Macroscopic roughness theta-bar (deg), in [0, 90). | |
| 57 | |||
| 58 | 3 | bool operator==(const HapkeParameters&) const = default; | |
| 59 | }; | ||
| 60 | |||
| 61 | /// Hapke parameters per `MaterialClass`; a class without any cannot be mixed. | ||
| 62 | using MaterialPhotometry = std::array<std::optional<HapkeParameters>, kMaterialClasses>; | ||
| 63 | |||
| 64 | /// Hapke parameters of Martian surfaces at 753 nm from Pancam (Johnson et al. 2006a, b, as | ||
| 65 | /// tabulated by Fernando et al. 2013, and Johnson et al. 2006b Table 2a): soil from Spirit's | ||
| 66 | /// landing site soil, sand from Opportunity's Purgatory ripples, dust from its dusty soil, bedrock | ||
| 67 | /// from its Eagle crater outcrop (w 0.90; 0.84 +- 0.06 averaged over sites, Table 11) and rock from | ||
| 68 | /// Spirit's dust-free gray rocks. | ||
| 69 | MaterialPhotometry MarsPancamPhotometry(); | ||
| 70 | |||
| 71 | /// Checks photometry parameters. | ||
| 72 | /// @throws std::invalid_argument for a parameter outside its range. | ||
| 73 | void ValidateMaterialPhotometry(const MaterialPhotometry& photometry); | ||
| 74 | |||
| 75 | /// The Hapke parameters of a mix of materials: each parameter the share-weighted mean of the | ||
| 76 | /// classes', an areal mix approximation. | ||
| 77 | /// @throws std::invalid_argument if a class with a share has no parameters. | ||
| 78 | HapkeParameters MixPhotometry(const MaterialShares& shares, const MaterialPhotometry& photometry); | ||
| 79 | |||
| 80 | /// Rasters of the albedo, b, c and roughness that the material rasters `materials` (one per | ||
| 81 | /// class, as `EvaluateMaterials` gives) mix to. | ||
| 82 | /// @throws std::invalid_argument for the wrong number of rasters, rasters on different grids, or | ||
| 83 | /// as `MixPhotometry`. | ||
| 84 | std::vector<Raster<float>> EvaluatePhotometry(const std::vector<Raster<float>>& materials, | ||
| 85 | const MaterialPhotometry& photometry); | ||
| 86 | |||
| 87 | } // namespace terraingen | ||
| 88 |