// 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 "Angle.h" // #include "Polar.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; SphericalOf(); SphericalOf(float distance, AngleOf horizontal, AngleOf vertical); 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; /// @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.horizontal, v.vertical); } friend SphericalOf operator*(float f, const SphericalOf& v) { return SphericalOf(v.distance * f, v.horizontal, v.vertical); // not correct, should be f * v.distance } 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.horizontal, v.vertical); } friend SphericalOf operator/(float f, const SphericalOf& v) { return SphericalOf(v.distance / f, v.horizontal, v.vertical); // not correct, should be f / v.distance } SphericalOf operator/=(float f); }; using SphericalSingle = SphericalOf; using Spherical16 = SphericalOf; using Spherical = SphericalSingle; /* /// @brief A spherical vector /// @details This is a vector in 3D space using a spherical coordinate system. /// It consists of a distance and the polar and elevation angles from a /// reference direction. The reference direction is typically thought of /// as a forward direction. struct Spherical { 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 Angle horizontalAngle; /// @brief The angle in the vertical plane in degrees. Positive is upward. /// @details The angle is automatically normalized to -180 .. 180 Angle verticalAngle; /// @brief Create a new spherical vector with zero degrees and distance Spherical(); /// @brief Create a new spherical vector /// @param distance The distance in meters /// @param horizontalAngle The angle in the horizontal plane in degrees, /// clockwise rotation /// @param verticalAngle The angle in the vertical plan in degrees, /// zero is forward, positive is upward Spherical(float distance, Angle horizontalAngle, Angle verticalAngle); /// @brief Convert polar coordinates to spherical coordinates /// @param polar The polar coordinate // Spherical(Polar polar); /// @brief Convert 3D carthesian coordinates to spherical coordinates /// @param v Vector in 3D carthesian coordinates; Spherical(Vector3 v); /// @brief A spherical vector with zero degree angles and distance const static Spherical zero; /// @brief A normalized forward-oriented vector const static Spherical forward; /// @brief A normalized back-oriented vector const static Spherical back; /// @brief A normalized right-oriented vector const static Spherical right; /// @brief A normalized left-oriented vector const static Spherical left; /// @brief A normalized up-oriented vector const static Spherical up; /// @brief A normalized down-oriented vector const static Spherical down; /// @brief Equality test to another vector /// @param v The vector to check against /// @return true: if it is identical to the given vector /// @note This uses float comparison to check equality which may have strange /// effects. Equality on floats should be avoided. bool operator==(const Spherical& v) const; /// @brief The vector length /// @param v The vector for which you need the length /// @return The vector length; inline static float Magnitude(const Spherical& v) { return v.distance; } /// @brief The vector length /// @return The vector length inline float magnitude() const { return this->distance; } /// @brief Convert the vector to a length of 1 /// @param v The vector to convert /// @return The vector normalized to a length of 1 static Spherical Normalize(const Spherical& v); /// @brief Convert the vector to a length of a /// @return The vector normalized to a length of 1 Spherical normalized() const; /// @brief Negate the vector /// @return The negated vector /// This will rotate the vector by 180 degrees horizontally and /// vertically. Distance will stay the same. Spherical operator-() const; /// @brief Subtract a spherical vector from this vector /// @param v The vector to subtract /// @return The result of the subtraction Spherical operator-(const Spherical& v) const; Spherical operator-=(const Spherical& v); /// @brief Add a spherical vector to this vector /// @param v The vector to add /// @return The result of the addition Spherical operator+(const Spherical& v) const; Spherical operator+=(const Spherical& 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 Spherical operator*(const Spherical& v, float f) { return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); } friend Spherical operator*(float f, const Spherical& v) { return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); // not correct, should be f * v.distance } Spherical 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 Spherical operator/(const Spherical& v, float f) { return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); } friend Spherical operator/(float f, const Spherical& v) { return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); // not correct, should be f / v.distance } Spherical operator/=(float f); /// /// The distance between two vectors /// /// The first vector /// The second vector /// The distance between the two vectors // static float Distance(const Spherical &s1, const Spherical &s2); static Angle AngleBetween(const Spherical& v1, const Spherical& v2); static Spherical Rotate(const Spherical& v, Angle horizontalAngle, Angle verticalAngle); static Spherical RotateHorizontal(const Spherical& v, Angle angle); static Spherical RotateVertical(const Spherical& v, Angle angle); }; */ } // namespace LinearAlgebra } // namespace Passer using namespace Passer::LinearAlgebra; #include "Polar.h" #include "Vector3.h" #endif