Skip to content

Commit

Permalink
improve vector operator overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
SizzinSeal committed Dec 28, 2024
1 parent 23b0bc2 commit ffdace3
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 89 deletions.
115 changes: 61 additions & 54 deletions include/units/Vector2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ template <isQuantity T> class Vector2D {
constexpr static Vector2D unitVector(Angle t) { return fromPolar(t, (T)1.0); }

/**
* @brief + operator overload
* @brief + operator overload. Adds the x and y components of two vectors
*
* This operator adds the x and y components of two vectors
* {a, b} + {c, d} = {a + c, b + d}
*
* @param other vector to add
Expand All @@ -70,9 +69,8 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief - operator overload
* @brief - operator overload. Substracts the x and y components of two vectors
*
* This operator subtracts the x and y components of two vectors
* {a, b} - {c, d} = {a - c, b - d}
*
* @param other vector to subtract
Expand All @@ -83,31 +81,52 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief * operator overload
* @brief * operator overload. Multiplies a vector by a quantity
*
* This operator multiplies the x and y components of a vector by a scalar
* a * {b, c} = {a * b, a * c}
* {a, b} * c = {a * c, b * c}
*
* @param factor scalar to multiply by
* @return Vector2D<T>
* @tparam Q the type of quantity to multiply the vector with
* @tparam R the quantity type of the resulting vector
*
* @param factor the quantity to multiple the vector by
* @return Vector2D<R>
*/
constexpr Vector2D<T> operator*(double factor) const { return Vector2D<T>(this->x * factor, this->y * factor); }
template <isQuantity Q, isQuantity R = Multiplied<T, Q>> constexpr Vector2D<R> operator*(Q factor) const {
return Vector2D<R>(this->x * factor, this->y * factor);
}

/**
* @brief / operator overload
* @brief * operator overload. Finds the dot product of 2 Vector2D objects
*
* {a, b} * {c, d} = (a * c) + (b * d)
*
* @tparam Q the type of quantity to use for the other vector
* @tparam R the type of quantity to use for the result
* @param other the vector to calculate the dot product with
* @return R the dot product
*/
template <isQuantity Q, isQuantity R = Multiplied<T, Q>> constexpr R operator*(const Vector2D<Q>& other) const {
return (this->x * other.x) + (this->y * other.y);
}

/**
* @brief / operator overload. Divides a vector by a quantity
*
* This operator divides the x and y components of a vector by a scalar
* {a, b} / c = {a / c, b / c}
*
* @param factor scalar to divide by
* @tparam Q the type of quantity to divide the vector with
* @tparam R the quantity type of the resulting vector
*
* @param factor the quantity to divide the vector by
* @return Vector2D<T>
*/
constexpr Vector2D<T> operator/(double factor) const { return Vector2D<T>(this->x / factor, this->y / factor); }
template <isQuantity Q, isQuantity R = Divided<T, Q>> Vector2D<R> constexpr operator/(Q factor) const {
return Vector2D<R>(this->x / factor, this->y / factor);
}

/**
* @brief += operator overload
* @brief += operator overload. Adds the components of two vectors and stores the result
*
* This operator adds the x and y components of two vectors and stores the result in the calling vector
* {a, b} += {c, d} => {a + c, b + d}
*
* @param other vector to add
Expand All @@ -120,9 +139,8 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief -= operator overload
* @brief -= operator overload. Subtracts the components of two vectors and stores the result
*
* This operator subtracts the x and y components of two vectors and stores the result in the calling vector
* {a, b} -= {c, d} => {a - c, b - d}
*
* @param other vector to subtract
Expand All @@ -135,11 +153,9 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief *= operator overload
* @brief *= operator overload. Multiplies the components of a vector by a scalar and stores the result
*
* This operator multiplies the x and y components of a vector by a scalar and stores the result in the
* calling vector
* a *= {b, c} => {a * b, a * c}
* {a, b} *= c => {a * c, b * c}
*
* @param factor scalar to multiply by
* @return Vector2D<T>&
Expand All @@ -151,10 +167,8 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief /= operator overload
* @brief /= operator overload. Divides the components of a vector by a scalar and stores the result
*
* This operator divides the x and y components of a vector by a scalar and stores the result in the
* calling vector
* {a, b} /= c => {a / c, b / c}
*
* @param factor scalar to divide by
Expand All @@ -167,22 +181,7 @@ template <isQuantity T> class Vector2D {
}

/**
* @brief dot product of 2 Vector2D objects
*
* This function calculates the dot product of two vectors
* a.dot(b) = (a.x * b.x) + (a.y * b.y)
*
* @tparam Q the type of quantity to use for the other vector
* @tparam R the type of quantity to use for the result
* @param other the vector to calculate the dot product with
* @return R the dot product
*/
template <isQuantity Q, isQuantity R = Multiplied<T, Q>> constexpr R dot(const Vector2D<Q>& other) const {
return (this->x * other.x) + (this->y * other.y);
}

/**
* @brief angle of the vector
* @brief angle of the vector from the origin
*
* @return Angle
*/
Expand Down Expand Up @@ -233,10 +232,7 @@ template <isQuantity T> class Vector2D {
*
* @return Vector2D<T>
*/
constexpr Vector2D<T> normalize() const {
const T m = magnitude();
return Vector2D<T>(this->x / m, this->y / m);
}
constexpr Vector2D<T> normalize() const { return (*this) / magnitude(); }

/**
* @brief rotate the vector by an angle
Expand Down Expand Up @@ -267,24 +263,35 @@ template <isQuantity T> class Vector2D {
* @param angle
* @return Vector2D<T>
*/
constexpr Vector2D<T> rotatedBy(Angle angle) const {
const T m = magnitude();
const Angle t = theta() + angle;
return fromPolar(t, m);
}
constexpr Vector2D<T> rotatedBy(Angle angle) const { return fromPolar(theta() + angle, magnitude()); }

/**
* @brief get a copy of this vector rotated to an angle
*
* @param angle
* @return Vector2D<T>
*/
constexpr Vector2D<T> rotatedTo(Angle angle) const {
const T m = magnitude();
return fromPolar(angle, m);
}
constexpr Vector2D<T> rotatedTo(Angle angle) const { return fromPolar(angle, magnitude()); }
};

/**
* @brief * operator overload. Multiplies a scalar and a vector
*
* a * {b, c} = {a * b, a * c}
*
* @tparam Q1 the quantity type of the scalar
* @tparam Q2 the quantity type of the vector
* @tparam Q3 the type of quantity to use for the result
*
* @param lhs the scalar on the left hand side
* @param rhs the vector on the right hand side
* @return Q3 the product
*/
template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Multiplied<Q1, Q2>>
constexpr Vector2D<Q3> operator*(Q1 lhs, const Vector2D<Q2>& rhs) {
return rhs * lhs;
}

// define some common vector types
typedef Vector2D<Length> V2Position;
typedef Vector2D<LinearVelocity> V2Velocity;
Expand Down
79 changes: 44 additions & 35 deletions include/units/Vector3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ template <isQuantity T> class Vector3D {
constexpr static Vector3D unitVector(const Vector3D<Angle>& t) { return fromPolar(t, (T)1.0); }

/**
* @brief + operator overload
* @brief + operator overload. Adds the components of two vectors
*
* This operator adds the x, y, and z components of two vectors
* {a, b, c} + {d, e, f} = {a + d, b + e, c + f}
*
* @param other vector to add
Expand All @@ -69,9 +68,8 @@ template <isQuantity T> class Vector3D {
}

/**
* @brief - operator overload
* @brief - operator overload. Subtracts the components of two vectors
*
* This operator subtracts the x, y, and z components of two vectors
* {a, b, c} - {d, e, f} = {a - d, b - e, c - f}
*
* @param other vector to subtract
Expand All @@ -82,35 +80,38 @@ template <isQuantity T> class Vector3D {
}

/**
* @brief * operator overload
* @brief * operator overload. Multiplies a vector by a quantity
*
* This operator multiplies the x, y, and z components of a vector by a scalar
* a * {b, c, d} = {a * b, a * c, a * d}
* {a, b, c} * d = {a * d, b * d, c * d}
*
* @param factor scalar to multiply by
* @return Vector3D<T>
* @tparam Q the type of quantity to multiply the vector with
* @tparam R the quantity type of the resulting vector
*
* @param factor the quantity to multiple the vector by
* @return Vector3D<R>
*/
constexpr Vector3D<T> operator*(double factor) const {
return Vector3D<T>(this->x * factor, this->y * factor, this->z * factor);
template <isQuantity Q, isQuantity R = Multiplied<T, Q>> constexpr Vector3D<R> operator*(Q factor) const {
return Vector3D<R>(this->x * factor, this->y * factor, this->z * factor);
}

/**
* @brief / operator overload
* @brief / operator overload. Multiplies a vector by a quantity
*
* This operator divides the x, y, and z components of a vector by a scalar
* {a, b, c} / d = {a / d, b / d, c / d}
*
* @param factor scalar to divide by
* @return Vector3D<T>
* @tparam Q the type of quantity to multiply the vector with
* @tparam R the quantity type of the resulting vector
*
* @param factor the quantity to multiple the vector by
* @return Vector3D<R>
*/
constexpr Vector3D<T> operator/(double factor) const {
return Vector3D<T>(this->x / factor, this->y / factor, this->z / factor);
template <isQuantity Q, isQuantity R = Divided<T, Q>> constexpr Vector3D<R> operator/(Q factor) const {
return Vector3D<R>(this->x / factor, this->y / factor, this->z / factor);
}

/**
* @brief += operator overload
* @brief += operator overload. Adds the components of two vectors and stores the result
*
* This operator adds the x, y, and z components of two vectors and stores the result in the calling vector
* {a, b, c} += {d, e, f} => {a + d, b + e, c + f}
*
* @param other vector to add
Expand All @@ -124,9 +125,8 @@ template <isQuantity T> class Vector3D {
}

/**
* @brief -= operator overload
* @brief -= operator overload. Subtracts the components of two vectors and stores the result
*
* This operator subtracts the x, y, and z components of two vectors and stores the result in the calling vector
* {a, b, c} -= {d, e, f} => {a - d, b - e, c - f}
*
* @param other vector to subtract
Expand All @@ -140,10 +140,8 @@ template <isQuantity T> class Vector3D {
}

/**
* @brief *= operator overload
* @brief *= operator overload. Multiplies the components of a vector by a scalar and stores the result.
*
* This operator multiplies the x, y, and z components of a vector by a scalar and stores the result in the
* calling vector
* a *= {b, c, d} => {a * b, a * c, a * d}
*
* @param factor scalar to multiply by
Expand All @@ -157,10 +155,8 @@ template <isQuantity T> class Vector3D {
}

/**
* @brief /= operator overload
* @brief /= operator overload. Divides the components of a vector by a scalar and stores the result
*
* This operator divides the x, y, and z components of a vector by a scalar and stores the result in the
* calling vector
* {a, b, c} /= d => {a / d, b / d, c / d}
*
* @param factor scalar to divide by
Expand Down Expand Up @@ -264,7 +260,7 @@ template <isQuantity T> class Vector3D {
*
* @return Vector3D<T>
*/
constexpr Vector3D<T> normalize() { return *(this) / magnitude(); }
constexpr Vector3D<T> normalize() { return (*this) / magnitude(); }

/**
* @brief rotate the vector by an angle
Expand Down Expand Up @@ -298,9 +294,7 @@ template <isQuantity T> class Vector3D {
* @return Vector3D<T>
*/
constexpr Vector3D<T> rotatedBy(const Vector3D<Angle>& angle) const {
const T m = magnitude();
const Angle t = theta() + angle;
return fromPolar(t, m);
return fromPolar(theta() + angle, magnitude());
}

/**
Expand All @@ -309,12 +303,27 @@ template <isQuantity T> class Vector3D {
* @param angle
* @return Vector3D<T>
*/
constexpr Vector3D<T> rotatedTo(Angle angle) const {
const T m = magnitude();
return fromPolar(angle, m);
}
constexpr Vector3D<T> rotatedTo(Angle angle) const { return fromPolar(angle, magnitude()); }
};

/**
* @brief * operator overload. Multiplies a scalar and a vector
*
* a * {b, c, d} = {a * b, a * c, a * d}
*
* @tparam Q1 the quantity type of the scalar
* @tparam Q2 the quantity type of the vector
* @tparam Q3 the type of quantity to use for the result
*
* @param lhs the scalar on the left hand side
* @param rhs the vector on the right hand side
* @return Q3 the product
*/
template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Multiplied<Q1, Q2>>
constexpr Vector3D<Q3> operator*(Q1 lhs, const Vector3D<Q2>& rhs) {
return rhs * lhs;
}

// define some common vector types
typedef Vector3D<Length> V3Position;
typedef Vector3D<LinearVelocity> V3Velocity;
Expand Down

0 comments on commit ffdace3

Please sign in to comment.