| 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 | |