diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 28ea44468..3712f0d09 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -62,8 +62,8 @@ namespace Nz String ToString() const; - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; const Vector2& operator+() const; Vector2 operator-() const; @@ -89,7 +89,9 @@ namespace Nz bool operator>(const Vector2& vec) const; bool operator>=(const Vector2& vec) const; + static T DotProduct(const Vector2& vec1, const Vector2& vec2); static Vector2 Lerp(const Vector2& from, const Vector2& to, T interpolation); + static Vector2 Normalize(const Vector2& vec); static Vector2 Unit(); static Vector2 UnitX(); static Vector2 UnitY(); diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 514aa3344..1876087f5 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -13,24 +13,54 @@ namespace Nz { + /*! + * \class Nz::Vector2 + * \brief Math class that represents an element of the two dimensional vector space + */ + + /*! + * \brief Constructs a Vector2 object from its coordinates + * + * \param X X component + * \param Y Y component + */ + template Vector2::Vector2(T X, T Y) { Set(X, Y); } + /*! + * \brief Constructs explicitely a Vector2 object from its "scale" + * + * \param scale X component = Y component + */ + template Vector2::Vector2(T scale) { Set(scale); } + /*! + * \brief Constructs a Vector2 object from an array of two elements + * + * \param vec[2] vec[0] is X component and vec[1] is Y component + */ + template Vector2::Vector2(const T vec[2]) { Set(vec); } + /*! + * \brief Constructs a Vector2 object from another type of Vector2 + * + * \param vec Vector of type U to convert to type T + */ + template template Vector2::Vector2(const Vector2& vec) @@ -38,60 +68,140 @@ namespace Nz Set(vec); } + /*! + * \brief Constructs a Vector2 object from a Vector3 + * + * \param vec Vector3 where only the first two components are taken + */ + template Vector2::Vector2(const Vector3& vec) { Set(vec); } + /*! + * \brief Constructs a Vector2 object from a Vector4 + * + * \param vec Vector4 where only the first two components are taken + */ + template Vector2::Vector2(const Vector4& vec) { Set(vec); } + /*! + * \brief Calculates the absolute dot (scalar) product with two vectors + * \return The dot product with absolutes values on each component + * + * \param vec The other vector to calculate the absolute dot product with + * + * \see DotProduct + */ + template T Vector2::AbsDotProduct(const Vector2& vec) const { return std::abs(x * vec.x) + std::abs(y * vec.y); } + /*! + * \brief Calculates the angle between two vectors in orthonormal basis + * \return The angle unit depends of NAZARA_MATH_ANGLE_RADIAN, you may want to normalize it to the range 0..2*pi with NormalizeAngle + * + * \param vec The other vector to measure the angle with + * + * \remark The vectors do not need to be normalised and if the angle is normalised, it represents the rotation from *this to vec in anti-clockwise direction + * + * \see NormalizeAngle + */ + template T Vector2::AngleBetween(const Vector2& vec) const { return FromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see SquaredDistance + */ + template T Vector2::Distance(const Vector2& vec) const { return std::sqrt(SquaredDistance(vec)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance in float between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + */ + template float Vector2::Distancef(const Vector2& vec) const { return std::sqrt(static_cast(SquaredDistance(vec))); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec The other vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector2::DotProduct(const Vector2& vec) const { return x*vec.x + y*vec.y; } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length of the vector + * + * \see GetSquaredLength + */ + template T Vector2::GetLength() const { - return std::sqrt(GetSquaredLength()); + return static_cast(std::sqrt(GetSquaredLength())); } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length in float of the vector + */ + template float Vector2::GetLengthf() const { return std::sqrt(static_cast(GetSquaredLength())); } + /*! + * \brief Gets a copy normalized of the vector + * \return A new vector which is the vector normalized + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If this vector is (0, 0), then it returns (0, 0) and length is 0 + * + * \see Normalize + */ + template Vector2 Vector2::GetNormal(T* length) const { @@ -101,36 +211,80 @@ namespace Nz return vec; } + /*! + * \brief Calculates the squared length (magnitude) of the vector + * \return The squared length of the vector + * + * \see GetLength + */ + template T Vector2::GetSquaredLength() const { return x*x + y*y; } + /*! + * \brief Makes the vector (1, 1) + * \return A reference to this vector with components (1, 1) + * + * \see Unit + */ + template Vector2& Vector2::MakeUnit() { return Set(F(1.0), F(1.0)); } + /*! + * \brief Makes the vector (1, 0) + * \return A reference to this vector with components (1, 0) + * + * \see UnitX + */ + template Vector2& Vector2::MakeUnitX() { return Set(F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 1) + * \return A reference to this vector with components (0, 1) + * + * \see UnitY + */ + template Vector2& Vector2::MakeUnitY() { return Set(F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 0) + * \return A reference to this vector with components (0, 0) + * + * \see Zero + */ + template Vector2& Vector2::MakeZero() { return Set(F(0.0), F(0.0)); } + /*! + * \brief Sets this vector's components to the maximum of its own and other components + * \return A reference to this vector with replaced values with the corresponding max value + * + * \param vec Other vector to compare the components with + * + * \see Minimize + */ + template Vector2& Vector2::Maximize(const Vector2& vec) { @@ -143,6 +297,15 @@ namespace Nz return *this; } + /*! + * \brief Sets this vector's components to the minimum of its own and other components + * \return A reference to this vector with replaced values with the corresponding min value + * + * \param vec Other vector to compare the components with + * + * \see Maximize + */ + template Vector2& Vector2::Minimize(const Vector2& vec) { @@ -155,6 +318,17 @@ namespace Nz return *this; } + /*! + * \brief Normalizes the current vector + * \return A reference to this vector + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If the vector is (0, 0), then it returns (0, 0) and length is 0 + * + * \see GetNormal + */ + template Vector2& Vector2::Normalize(T* length) { @@ -172,6 +346,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + */ + template Vector2& Vector2::Set(T X, T Y) { @@ -181,6 +363,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a "scale" + * \return A reference to this vector + * + * \param scale X component = Y component + */ + template Vector2& Vector2::Set(T scale) { @@ -190,6 +379,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from an array of two elements + * \return A reference to this vector + * + * \param vec[2] vec[0] is X component and vec[1] is Y component + */ + template Vector2& Vector2::Set(const T vec[2]) { @@ -198,6 +394,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another vector + * \return A reference to this vector + * + * \param vec The other vector + */ + template Vector2& Vector2::Set(const Vector2& vec) { @@ -206,6 +409,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another type of Vector2 + * \return A reference to this vector + * + * \param vec Vector of type U to convert its components + */ + template template Vector2& Vector2::Set(const Vector2& vec) @@ -216,6 +426,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector3 + * \return A reference to this vector + * + * \param vec Vector3 where only the first two components are taken + */ + template Vector2& Vector2::Set(const Vector3& vec) { @@ -225,6 +442,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector4 + * \return A reference to this vector + * + * \param vec Vector4 where only the first two components are taken + */ + template Vector2& Vector2::Set(const Vector4& vec) { @@ -234,12 +458,26 @@ namespace Nz return *this; } + /*! + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see Distance + */ + template T Vector2::SquaredDistance(const Vector2& vec) const { return (*this - vec).GetSquaredLength(); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Vector2(x, y)" + */ + template String Vector2::ToString() const { @@ -248,54 +486,116 @@ namespace Nz return ss << "Vector2(" << x << ", " << y << ')'; } + /*! + * \brief Converts vector to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 1 is undefined behavior + */ + template - Vector2::operator T*() + Vector2::operator T* () { return &x; } + /*! + * \brief Converts vector to const pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 1 is undefined behavior + */ + template - Vector2::operator const T*() const + Vector2::operator const T* () const { return &x; } + /*! + * \brief Helps to represent the sign of the vector + * \return A constant reference to this vector + */ + template const Vector2& Vector2::operator+() const { return *this; } + /*! + * \brief Negates the components of the vector + * \return A constant reference to this vector with negate components + */ + template Vector2 Vector2::operator-() const { return Vector2(-x, -y); } + /*! + * \brief Adds the components of the vector with other vector + * \return A vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector2 Vector2::operator+(const Vector2& vec) const { return Vector2(x + vec.x, y + vec.y); } + /*! + * \brief Substracts the components of the vector with other vector + * \return A vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector2 Vector2::operator-(const Vector2& vec) const { return Vector2(x - vec.x, y - vec.y); } + /*! + * \brief Multiplies the components of the vector with other vector + * \return A vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector2 Vector2::operator*(const Vector2& vec) const { return Vector2(x * vec.x, y * vec.y); } + /*! + * \brief Multiplies the components of the vector with a scalar + * \return A vector where components are the product of this vector and the scalar + * + * \param scale The scalar to multiply components with + */ + template Vector2 Vector2::operator*(T scale) const { return Vector2(x * scale, y * scale); } + /*! + * \brief Divides the components of the vector with other vector + * \return A vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector2 Vector2::operator/(const Vector2& vec) const { @@ -312,6 +612,16 @@ namespace Nz return Vector2(x / vec.x, y / vec.y); } + /*! + * \brief Divides the components of the vector with a scalar + * \return A vector where components are the quotient of this vector and the scalar + * + * \param scale The scalar to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector2 Vector2::operator/(T scale) const { @@ -328,6 +638,13 @@ namespace Nz return Vector2(x / scale, y / scale); } + /*! + * \brief Adds the components of other vector to this vector + * \return A reference to this vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector2& Vector2::operator+=(const Vector2& vec) { @@ -337,6 +654,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other vector to this vector + * \return A reference to this vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector2& Vector2::operator-=(const Vector2& vec) { @@ -346,6 +670,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector2& Vector2::operator*=(const Vector2& vec) { @@ -355,6 +686,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector with a scalar + * \return A reference to this vector where components are the product of this vector and the scalar + * + * \param vec The other vector to multiply components with + */ + template Vector2& Vector2::operator*=(T scale) { @@ -364,6 +702,16 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to multiply components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector2& Vector2::operator/=(const Vector2& vec) { @@ -383,6 +731,16 @@ namespace Nz return *this; } + /*! + * \brief Divides the components of other vector with a scalar + * \return A reference to this vector where components are the quotient of this vector and the scalar + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector2& Vector2::operator/=(T scale) { @@ -402,19 +760,40 @@ namespace Nz return *this; } + /*! + * \brief Compares the vector to other one + * \return true if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator==(const Vector2& vec) const { return NumberEquals(x, vec.x) && - NumberEquals(y, vec.y); + NumberEquals(y, vec.y); } + /*! + * \brief Compares the vector to other one + * \return false if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator!=(const Vector2& vec) const { return !operator==(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator<(const Vector2& vec) const { @@ -424,6 +803,13 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator<=(const Vector2& vec) const { @@ -433,24 +819,95 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator>(const Vector2& vec) const { return !operator<=(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator>=(const Vector2& vec) const { return !operator<(vec); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec1 The first vector to calculate the dot product with + * \param vec2 The second vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + + template + T Vector2::DotProduct(const Vector2& vec1, const Vector2& vec2) + { + return vec1.DotProduct(vec2); + } + + /*! + * \brief Interpolates the vector to other one with a factor of interpolation + * \return A new vector which is the interpolation of two vectors + * + * \param from Initial vector + * \param to Target vector + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + template Vector2 Vector2::Lerp(const Vector2& from, const Vector2& to, T interpolation) { - return Lerp(from, to, interpolation); + Vector2 dummy; + dummy.x = Nz::Lerp(from.x, to.x, interpolation); + dummy.y = Nz::Lerp(from.y, to.y, interpolation); + + return dummy; } + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec + * + * \param vec Vector to normalize + * + * \remark If the vector is (0, 0), then it returns (0, 0) + * + * \see GetNormal + */ + + template + Vector2 Vector2::Normalize(const Vector2& vec) + { + return vec.GetNormal(); + } + + /*! + * \brief Shorthand for the vector (1, 1) + * \return A vector with components (1, 1) + * + * \see MakeUnit + */ + template Vector2 Vector2::Unit() { @@ -460,6 +917,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 0) + * \return A vector with components (1, 0) + * + * \see MakeUnitX + */ + template Vector2 Vector2::UnitX() { @@ -469,6 +933,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1) + * \return A vector with components (0, 1) + * + * \see MakeUnitY + */ + template Vector2 Vector2::UnitY() { @@ -478,6 +949,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0) + * \return A vector with components (0, 0) + * + * \see MakeZero + */ + template Vector2 Vector2::Zero() { @@ -488,18 +966,43 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param vec The vector to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec) { return out << vec.ToString(); } +/*! +* \brief Multiplies the components of the vector with a scalar +* \return A vector where components are the product of this vector and the scalar +* +* \param scale The scalar to multiply components with +*/ + template Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) { return Nz::Vector2(scale * vec.x, scale * vec.y); } +/*! +* \brief Divides the components of the vector with a scalar +* \return A vector where components are the quotient of this vector and the scalar +* +* \param scale The scalar to divide components with +* +* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined +* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null +*/ + template Nz::Vector2 operator/(T scale, const Nz::Vector2& vec) { @@ -513,7 +1016,7 @@ Nz::Vector2 operator/(T scale, const Nz::Vector2& vec) } #endif - return Nz::Vector2(scale/vec.x, scale/vec.y); + return Nz::Vector2(scale / vec.x, scale / vec.y); } #undef F