// 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 VECTOR2_H #define VECTOR2_H #include "Angle.h" extern "C" { /// /// 2-dimensional Vector representation /// /// This is a C-style implementation /// This uses the right-handed coordinate system. typedef struct Vec2 { /// /// The right axis of the vector /// float x; /// /// The upward/forward axis of the vector /// float y; } Vec2; } namespace Passer { namespace LinearAlgebra { struct Vector3; struct Polar; /// @brief A 2=dimensional vector /// @remark This uses the right=handed carthesian coordinate system. /// @note This implementation intentionally avoids the use of x and y struct Vector2 : Vec2 { friend struct Vec2; public: /// @brief A new 2-dimensional zero vector Vector2(); /// @brief A new 2-dimensional vector /// @param right The distance in the right direction in meters /// @param forward The distance in the forward direction in meters Vector2(float right, float forward); /// @brief Convert a Vector3 to a Vector2 /// @param v The 3D vector /// @note This will project the vector to the horizontal plane Vector2(Vector3 v); /// @brief Convert a Polar vector to a 2-dimensional vector /// @param v The vector in polar coordinates Vector2(Polar v); /// @brief Vector2 destructor ~Vector2(); /// @brief A vector with zero for all axis const static Vector2 zero; /// @brief A vector with one for all axis const static Vector2 one; /// @brief A normalized forward-oriented vector const static Vector2 forward; /// @brief A normalized back-oriented vector const static Vector2 back; /// @brief A normalized right-oriented vector const static Vector2 right; /// @brief A normalized left-oriented vector const static Vector2 left; /// @brief A normalized up-oriented vector /// @note This is a convenience function which is equal to Vector2::forward const static Vector2 up; /// @brief A normalized down-oriented vector /// @note This is a convenience function which is equal to Vector2::down const static Vector2 down; /// @brief Check if this vector to the given 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 Vector2 &v); /// @brief The vector length /// @param v The vector for which you need the length /// @return The vector length static float Magnitude(const Vector2 &v); /// @brief The vector length /// @return The vector length float magnitude() const; /// @brief The squared vector length /// @param v The vector for which you need the squared length /// @return The squared vector length /// @remark The squared length is computationally simpler than the real /// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation /// of the squared root of C. static float SqrMagnitude(const Vector2 &v); /// @brief The squared vector length /// @return The squared vector length /// @remark The squared length is computationally simpler than the real /// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation /// of the squared root of C. float sqrMagnitude() const; /// @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 Vector2 Normalize(const Vector2 &v); /// @brief Convert the vector to a length 1 /// @return The vector normalized to a length of 1 Vector2 normalized() const; /// @brief Negate the vector such that it points in the opposite direction /// @return The negated vector Vector2 operator-(); /// @brief Subtract a vector from this vector /// @param v The vector to subtract from this vector /// @return The result of the subtraction Vector2 operator-(const Vector2 &v) const; Vector2 operator-=(const Vector2 &v); /// @brief Add a vector to this vector /// @param v The vector to add to this vector /// @return The result of the addition Vector2 operator+(const Vector2 &v) const; Vector2 operator+=(const Vector2 &v); /// @brief Scale the vector using another vector /// @param v1 The vector to scale /// @param v2 A vector with the scaling factors /// @return The scaled vector /// @remark Each component of the vector v1 will be multiplied with the /// matching component from the scaling vector v2. static Vector2 Scale(const Vector2 &v1, const Vector2 &v2); /// @brief Scale the vector uniformly up /// @param f The scaling factor /// @return The scaled vector /// @remark Each component of the vector will be multipled with the same /// factor f. friend Vector2 operator*(const Vector2 &v, float f); friend Vector2 operator*(float f, const Vector2 &v); Vector2 operator*=(float f); /// @brief Scale the vector uniformly down /// @param f The scaling factor /// @return The scaled vector /// @remark Each componet of the vector will be divided by the same factor. friend Vector2 operator/(const Vector2 &v, float f); friend Vector2 operator/(float f, const Vector2 &v); Vector2 operator/=(float f); /// @brief The dot product of two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The dot product of the two vectors static float Dot(const Vector2 &v1, const Vector2 &v2); /// @brief The distance between two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The distance between the two vectors static float Distance(const Vector2 &v1, const Vector2 &v2); /// @brief The angle between two vectors /// @param v1 The first vector /// @param v2 The second vector /// @return The angle between the two vectors /// @remark This reterns an unsigned angle which is the shortest distance /// between the two vectors. Use Vector2::SignedAngle if a signed angle is /// needed. static float Angle(const Vector2 &v1, const Vector2 &v2); /// @brief The signed angle between two vectors /// @param v1 The starting vector /// @param v2 The ending vector /// @return The signed angle between the two vectors static float SignedAngle(const Vector2 &v1, const Vector2 &v2); /// @brief Rotate the vector /// @param v The vector to rotate /// @param a The angle in degrees to rotate /// @return The rotated vector static Vector2 Rotate(const Vector2 &v, Passer::LinearAlgebra::Angle a); /// @brief Lerp (linear interpolation) between two vectors /// @param v1 The starting vector /// @param v2 The end vector /// @param f The interpolation distance /// @return The lerped vector /// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value /// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference /// between *v1* and *v2* etc. static Vector2 Lerp(const Vector2 &v1, const Vector2 &v2, float f); }; } // namespace LinearAlgebra } // namespace Passer using namespace Passer::LinearAlgebra; #include "Polar.h" #endif