TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
18 / 18
100.0%
Branches:
5 / 10
50.0%
Functions:
7 / 7
100.0%

util/radial_shape.h
Line Branch Exec Source
1 /// @file
2 /// @brief `RadialShape`, a star-shaped body's radius along each direction from its centre.
3 #pragma once
4
5 #include "terraingen/util/geometry.h"
6
7 #include <cstddef>
8 #include <functional>
9 #include <vector>
10
11 namespace terraingen {
12
13 /// The radius of a star-shaped body (one every ray from its centre crosses once) along each
14 /// direction: a radial ICQ grid, the vertex labels (I, J, F) of Gaskell's implicitly connected
15 /// quadrilateral format (I and J from 0 to Q, faces F from 1 to 6 centred on +z, -y, -x, +y, +x
16 /// and -z) each at a fixed equiangular direction, holding the radius there. Within each of a
17 /// face's Q^2 quadrilaterals the radius is interpolated bilinearly in those angles. Labels the
18 /// format shares between faces have the same direction and radius, so the radius is continuous;
19 /// it never leaves the range of the label radii.
20 class RadialShape {
21 public:
22 /// The shape of `q` intervals per face edge from a radius in metres along each unit direction,
23 /// evaluated at every label.
24 /// @throws std::invalid_argument for a `q` of 0, or a radius that is not positive and finite.
25 static RadialShape Sample(std::size_t q, const std::function<double(const Vec3d&)>& radius);
26
27 /// The shape of `q` intervals per face edge from 6 (q + 1)^2 label radii in metres, in ICQ
28 /// file order (`LabelIndex`).
29 /// @throws std::invalid_argument for a `q` of 0, the wrong count, a radius that is not
30 /// positive and finite, or labels shared between faces with different radii.
31 RadialShape(std::size_t q, std::vector<double> radii);
32
33 /// The unit direction of label (`i`, `j`, `face`) of a grid of `q` intervals per edge, at
34 /// equiangular coordinates with Gaskell's face orientation: on face 1 (+z) I runs along +x and
35 /// J along -y; on faces 2 to 5 (-y, -x, +y, +x) J runs along -z; on face 6 (-z) I runs along +x
36 /// and J along +y. Labels the format shares between faces get the same direction exactly.
37 /// @throws std::invalid_argument unless `q` > 0, `i` and `j` <= `q` and 1 <= `face` <= 6.
38 static Vec3d LabelDirection(std::size_t q, std::size_t i, std::size_t j, std::size_t face);
39
40 /// The index of label (`i`, `j`, `face`) in the label radii, `face` from 1 to 6: ICQ file
41 /// order, face, then J, then I.
42 34432982 std::size_t LabelIndex(std::size_t i, std::size_t j, std::size_t face) const {
43 34432982 return ((face - 1) * (q_ + 1) + j) * (q_ + 1) + i;
44 }
45
46 /// The radius in metres along a nonzero `direction`.
47 double At(const Vec3d& direction) const;
48
49 /// Q, the intervals per face edge.
50 14 std::size_t Q() const {
51 14 return q_;
52 }
53
54 /// The label radii in metres, in the order of `LabelIndex`.
55 5402 const std::vector<double>& Radii() const {
56 5402 return radii_;
57 }
58
59 /// The smallest label radius in metres, a lower bound of `At`.
60 2013 double MinRadius() const {
61 2013 return min_;
62 }
63
64 /// The largest label radius in metres, an upper bound of `At`.
65 2418 double MaxRadius() const {
66 2418 return max_;
67 }
68
69 /// An upper bound in m^2 of the area per steradian, r^2 / (u . n), over the interpolated
70 /// surface: its largest value at any quadrilateral's corner with the quadrilateral's mean
71 /// normal (from the cross product of its diagonals), times a margin for the variation within
72 /// quadrilaterals.
73 5100 double MaxAreaPerSteradian() const {
74 5100 return maxArea_;
75 }
76
77 /// Whether two shapes have the same Q and label radii.
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 bool operator==(const RadialShape&) const = default;
79
80 private:
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 std::size_t q_ = 0;
82 3 std::vector<double> radii_;
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 double min_ = 0.0;
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 double max_ = 0.0;
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 double maxArea_ = 0.0;
86 };
87
88 } // namespace terraingen
89