// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0.If a copy of the MPL was not distributed with this // file, You can obtain one at https ://mozilla.org/MPL/2.0/. #ifndef SPHERICAL_H #define SPHERICAL_H #include "Direction.h" namespace Passer { namespace LinearAlgebra { struct Vector3; template class PolarOf; template class SphericalOf { public: /// @brief The distance in meters /// @remark The distance should never be negative float distance; /// @brief The angle in the horizontal plane in degrees, clockwise rotation /// @details The angle is automatically normalized to -180 .. 180 // AngleOf horizontal; /// @brief The angle in the vertical plane in degrees. Positive is upward. /// @details The angle is automatically normalized to -180 .. 180 // AngleOf vertical; DirectionOf direction; SphericalOf(); SphericalOf(float distance, AngleOf horizontal, AngleOf vertical); SphericalOf(float distance, DirectionOf direction); static SphericalOf FromPolar(PolarOf v); static SphericalOf FromVector3(Vector3 v); Vector3 ToVector3() const; /// @brief A spherical vector with zero degree angles and distance const static SphericalOf zero; /// @brief A normalized forward-oriented vector const static SphericalOf forward; /// @brief A normalized back-oriented vector const static SphericalOf back; /// @brief A normalized right-oriented vector const static SphericalOf right; /// @brief A normalized left-oriented vector const static SphericalOf left; /// @brief A normalized up-oriented vector const static SphericalOf up; /// @brief A normalized down-oriented vector const static SphericalOf down; SphericalOf WithDistance(float distance); /// @brief Negate the vector /// @return The negated vector /// This will rotate the vector by 180 degrees horizontally and /// vertically. Distance will stay the same. SphericalOf operator-() const; /// @brief Subtract a spherical vector from this vector /// @param v The vector to subtract /// @return The result of the subtraction SphericalOf operator-(const SphericalOf &v) const; SphericalOf operator-=(const SphericalOf &v); /// @brief Add a spherical vector to this vector /// @param v The vector to add /// @return The result of the addition SphericalOf operator+(const SphericalOf &v) const; SphericalOf operator+=(const SphericalOf &v); /// @brief Scale the vector uniformly up /// @param f The scaling factor /// @return The scaled vector /// @remark This operation will scale the distance of the vector. The angle /// will be unaffected. friend SphericalOf operator*(const SphericalOf &v, float f) { return SphericalOf(v.distance * f, v.direction); } friend SphericalOf operator*(float f, const SphericalOf &v) { return SphericalOf(f * v.distance, v.direction); } SphericalOf operator*=(float f); /// @brief Scale the vector uniformly down /// @param f The scaling factor /// @return The scaled factor /// @remark This operation will scale the distance of the vector. The angle /// will be unaffected. friend SphericalOf operator/(const SphericalOf &v, float f) { return SphericalOf(v.distance / f, v.direction); } friend SphericalOf operator/(float f, const SphericalOf &v) { return SphericalOf(f / v.distance, v.direction); } SphericalOf operator/=(float f); static float DistanceBetween(const SphericalOf &v1, const SphericalOf &v2); static AngleOf AngleBetween(const SphericalOf &v1, const SphericalOf &v2); static AngleOf SignedAngleBetween(const SphericalOf &v1, const SphericalOf &v2, const SphericalOf &axis); static SphericalOf Rotate(const SphericalOf &v, AngleOf horizontalAngle, AngleOf verticalAngle); static SphericalOf RotateHorizontal(const SphericalOf &v, AngleOf angle); static SphericalOf RotateVertical(const SphericalOf &v, AngleOf angle); }; using SphericalSingle = SphericalOf; using Spherical16 = SphericalOf; } // namespace LinearAlgebra } // namespace Passer using namespace Passer::LinearAlgebra; #include "Polar.h" #include "Vector3.h" #endif