1 | #pragma once |
2 | |
3 | #include <mbgl/util/constants.hpp> |
4 | |
5 | #include <array> |
6 | |
7 | namespace mbgl { |
8 | namespace style { |
9 | class Position { |
10 | public: |
11 | Position() = default; |
12 | Position(std::array<float, 3>& position_) |
13 | : radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) { |
14 | calculateCartesian(); |
15 | }; |
16 | |
17 | friend bool operator==(const Position& lhs, const Position& rhs) { |
18 | return lhs.radial == rhs.radial && lhs.azimuthal == rhs.azimuthal && lhs.polar == rhs.polar; |
19 | // TODO this doesn't address wrapping, which would be better addressed by comparing cartesian coordinates but being calculated floats are ont to be trusted. |
20 | } |
21 | |
22 | friend bool operator!=(const Position& lhs, const Position& rhs) { |
23 | return !(lhs == rhs); |
24 | } |
25 | |
26 | const std::array<float, 3> getCartesian() const { |
27 | return { ._M_elems: { x, y, z } }; |
28 | }; |
29 | |
30 | const std::array<float, 3> getSpherical() const { |
31 | return { ._M_elems: { radial, azimuthal, polar } }; |
32 | }; |
33 | |
34 | void set(std::array<float, 3>& position_) { |
35 | radial = position_[0]; |
36 | azimuthal = position_[1]; |
37 | polar = position_[2]; |
38 | calculateCartesian(); |
39 | }; |
40 | |
41 | // Utility function to be used only during interpolation; this leaves spherical coordinates undefined. |
42 | void setCartesian(std::array<float, 3>& position_) { |
43 | x = position_[0]; |
44 | y = position_[1]; |
45 | z = position_[2]; |
46 | } |
47 | |
48 | private: |
49 | float radial; |
50 | float azimuthal; |
51 | float polar; |
52 | float x; |
53 | float y; |
54 | float z; |
55 | |
56 | void calculateCartesian() { |
57 | // We abstract "north"/"up" (compass-wise) to be 0° when really this is 90° (π/2): we |
58 | // correct for that here |
59 | const float _a = (azimuthal + 90) * util::DEG2RAD; |
60 | const float _p = polar * util::DEG2RAD; |
61 | |
62 | x = radial * std::cos(x: _a) * std::sin(x: _p); |
63 | y = radial * std::sin(x: _a) * std::sin(x: _p); |
64 | z = radial * std::cos(x: _p); |
65 | }; |
66 | }; |
67 | } // namespace style |
68 | } // namespace mbgl |
69 | |