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;
Position(std::array<float,3> & position_)12     Position(std::array<float, 3>& position_)
13         : radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) {
14         calculateCartesian();
15     };
16 
operator ==(const Position & lhs,const Position & rhs)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 
operator !=(const Position & lhs,const Position & rhs)22     friend bool operator!=(const Position& lhs, const Position& rhs) {
23         return !(lhs == rhs);
24     }
25 
getCartesian() const26     const std::array<float, 3> getCartesian() const {
27         return { { x, y, z } };
28     };
29 
getSpherical() const30     const std::array<float, 3> getSpherical() const {
31         return { { radial, azimuthal, polar } };
32     };
33 
set(std::array<float,3> & position_)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.
setCartesian(std::array<float,3> & position_)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 
calculateCartesian()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(_a) * std::sin(_p);
63         y = radial * std::sin(_a) * std::sin(_p);
64         z = radial * std::cos(_p);
65     };
66 };
67 } // namespace style
68 } // namespace mbgl
69