Implement Vector3::ScaleToLength & ToString()
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <J3ML/LinearAlgebra/Angle2D.h>
|
||||
#include <J3ML/Algorithm/RNG.h>
|
||||
#include <J3ML/Algorithm/RNG.hpp>
|
||||
|
||||
|
||||
using namespace J3ML::Algorithm;
|
||||
@@ -144,7 +144,7 @@ public:
|
||||
@note If you have a non-const instance of this class, you can use this notation to set the elements of
|
||||
this vector as well, e.g. vec.At(1) = 10.f; would set the y-component of this vector.
|
||||
@see ptr(), operator [](). */
|
||||
float At(int index) const;
|
||||
[[nodiscard]] float At(int index) const;
|
||||
float &At(int index);
|
||||
|
||||
/// Makes the given vectors linearly independent and normalized in length.
|
||||
@@ -161,36 +161,47 @@ public:
|
||||
static bool AreOrthonormal(const Vector3& a, const Vector3& b, float epsilon = 1e-3f);
|
||||
static bool AreOrthonormal(const Vector3& a, const Vector3& b, const Vector3& c, float epsilon = 1e-3f);
|
||||
|
||||
Vector3 Abs() const;
|
||||
[[nodiscard]] Vector3 Abs() const;
|
||||
static Vector3 Abs(const Vector3& rhs);
|
||||
|
||||
/// Returns the DirectionVector for a given angle.
|
||||
static Vector3 Direction(const Vector3 &rhs) ;
|
||||
|
||||
/// Scales this vector so that its new length is as given.
|
||||
/** Calling this function is effectively the same as normalizing the vector first and then multiplying by newLength.
|
||||
In the case of failure, this vector is set to (newLength, 0, 0), so calling this function will never result in an
|
||||
unnormalized vector.
|
||||
@note This function operates in-place.
|
||||
@return The old length of this vector. If this function returns 0, the scaling failed, and this vector is arbitrarily
|
||||
reset to (newLength, 0, 0). In case of failure, no error message is generated. You are expected to handle the failure
|
||||
yourself.
|
||||
@see ScaledToLength(). */
|
||||
float ScaleToLength(float newLength);
|
||||
|
||||
|
||||
[[nodiscard]] Vector3 ProjectToNorm(const Vector3& direction) const;
|
||||
|
||||
|
||||
Vector3 ProjectToNorm(const Vector3& direction) const;
|
||||
|
||||
float GetX() const;
|
||||
float GetY() const;
|
||||
float GetZ() const;
|
||||
[[nodiscard]] float GetX() const;
|
||||
[[nodiscard]] float GetY() const;
|
||||
[[nodiscard]] float GetZ() const;
|
||||
void SetX(float newX);
|
||||
void SetY(float newY);
|
||||
void SetZ(float newZ);
|
||||
|
||||
bool IsWithinMarginOfError(const Vector3& rhs, float margin=0.001f) const;
|
||||
bool IsNormalized(float epsilonSq = 1e-5f) const;
|
||||
bool IsZero(float epsilonSq = 1e-6f) const;
|
||||
bool IsPerpendicular(const Vector3& other, float epsilonSq=1e-5f) const;
|
||||
[[nodiscard]] Vector2 XY() const { return {x, y};}
|
||||
|
||||
|
||||
[[nodiscard]] bool IsWithinMarginOfError(const Vector3& rhs, float margin=0.001f) const;
|
||||
[[nodiscard]] bool IsNormalized(float epsilonSq = 1e-5f) const;
|
||||
[[nodiscard]] bool IsZero(float epsilonSq = 1e-6f) const;
|
||||
[[nodiscard]] bool IsPerpendicular(const Vector3& other, float epsilonSq=1e-5f) const;
|
||||
|
||||
|
||||
bool operator == (const Vector3& rhs) const;
|
||||
bool operator != (const Vector3& rhs) const;
|
||||
|
||||
bool IsFinite() const;
|
||||
float MinElement() const;
|
||||
[[nodiscard]] bool IsFinite() const;
|
||||
[[nodiscard]] float MinElement() const;
|
||||
static float MinElement(const Vector3& of);
|
||||
|
||||
/// Normalizes this Vector3.
|
||||
@@ -207,62 +218,62 @@ public:
|
||||
/// Computes a new normalized direction vector that is perpendicular to this vector and the specified hint vector.
|
||||
/** If this vector points toward the hint vector, the vector hint2 is returned instead.
|
||||
@see AnotherPerpendicular(), Cross(). */
|
||||
Vector3 Perpendicular(const Vector3 &hint = Vector3(0,1,0), const Vector3 &hint2 = Vector3(0,0,1)) const;
|
||||
[[nodiscard]] Vector3 Perpendicular(const Vector3 &hint = Vector3(0,1,0), const Vector3 &hint2 = Vector3(0,0,1)) const;
|
||||
|
||||
Vector3 Min(const Vector3& min) const;
|
||||
[[nodiscard]] Vector3 Min(const Vector3& min) const;
|
||||
static Vector3 Min(const Vector3& a, const Vector3& b, const Vector3& c);
|
||||
static Vector3 Min(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
Vector3 Max(const Vector3& max) const;
|
||||
[[nodiscard]] Vector3 Max(const Vector3& max) const;
|
||||
static Vector3 Max(const Vector3& a, const Vector3& b, const Vector3& c);
|
||||
static Vector3 Max(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
Vector3 Clamp(const Vector3& min, const Vector3& max) const;
|
||||
[[nodiscard]] Vector3 Clamp(const Vector3& min, const Vector3& max) const;
|
||||
static Vector3 Clamp(const Vector3& min, const Vector3& input, const Vector3& max);
|
||||
|
||||
/// Returns the magnitude between the two vectors.
|
||||
float Distance(const Vector3& to) const;
|
||||
[[nodiscard]] float Distance(const Vector3& to) const;
|
||||
static float Distance(const Vector3& from, const Vector3& to);
|
||||
//float Distance(const Ray&) const;
|
||||
//float Distance(const LineSegment&) const;
|
||||
//float Distance(const Plane&) const;
|
||||
//float DIstance(const Triangle&) const;
|
||||
|
||||
float DistanceSquared(const Vector3& to) const;
|
||||
[[nodiscard]] float DistanceSquared(const Vector3& to) const;
|
||||
// Function Alias for DistanceSquared
|
||||
float DistanceSq(const Vector3& to) const { return DistanceSquared(to); }
|
||||
[[nodiscard]] float DistanceSq(const Vector3& to) const { return DistanceSquared(to); }
|
||||
static float DistanceSquared(const Vector3& from, const Vector3& to);
|
||||
|
||||
float Length() const;
|
||||
[[nodiscard]] float Length() const;
|
||||
static float Length(const Vector3& of);
|
||||
|
||||
float LengthSquared() const;
|
||||
[[nodiscard]] float LengthSquared() const;
|
||||
static float LengthSquared(const Vector3& of);
|
||||
|
||||
/// Returns the length of the vector, which is sqrt(x^2 + y^2 + z^2)
|
||||
float Magnitude() const;
|
||||
[[nodiscard]] float Magnitude() const;
|
||||
static float Magnitude(const Vector3& of);
|
||||
|
||||
/// Returns a float value equal to the magnitudes of the two vectors multiplied together and then multiplied by the cosine of the angle between them.
|
||||
/// For normalized vectors, dot returns 1 if they point in exactly the same direction,
|
||||
/// -1 if they point in completely opposite directions, and 0 if the vectors are perpendicular.
|
||||
float Dot(const Vector3& rhs) const;
|
||||
[[nodiscard]] float Dot(const Vector3& rhs) const;
|
||||
static float Dot(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// Projects one vector onto another and returns the result. (IDK)
|
||||
Vector3 Project(const Vector3& rhs) const;
|
||||
[[nodiscard]] Vector3 Project(const Vector3& rhs) const;
|
||||
static Vector3 Project(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// The cross product of two vectors results in a third vector which is perpendicular to the two input vectors.
|
||||
/// The result's magnitude is equal to the magnitudes of the two inputs multiplied together and then multiplied by the sine of the angle between the inputs.
|
||||
Vector3 Cross(const Vector3& rhs) const;
|
||||
[[nodiscard]] Vector3 Cross(const Vector3& rhs) const;
|
||||
static Vector3 Cross(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// Returns a copy of this vector, resized to have a magnitude of 1, while preserving "direction"
|
||||
/// @note If the vector is zero and cannot be normalized, the vector (1, 0, 0) is returned, and an error message is printed.
|
||||
/// If you do not want to generate an error message on failure, but want to handle the failure yourself, use the Normalize() function instead.
|
||||
/// @see Normalize()
|
||||
Vector3 Normalized() const;
|
||||
[[nodiscard]] Vector3 Normalized() const;
|
||||
static Vector3 Normalized(const Vector3& targ);
|
||||
|
||||
/// Normalizes this Vector3.
|
||||
@@ -281,56 +292,56 @@ public:
|
||||
/// Interpolates between the points and b by the interpolant t.
|
||||
/// The parameter is (TODO: SHOULD BE!) clamped to the range[0, 1].
|
||||
/// This is most commonly used to find a point some fraction of the wy along a line between two endpoints (eg. to move an object gradually between those points).
|
||||
Vector3 Lerp(const Vector3& goal, float alpha) const;
|
||||
[[nodiscard]] Vector3 Lerp(const Vector3& goal, float alpha) const;
|
||||
static Vector3 Lerp(const Vector3& lhs, const Vector3& rhs, float alpha);
|
||||
|
||||
/// Returns the angle between this vector and the specified vector, in radians.
|
||||
/** @note This function takes into account that this vector or the other vector can be unnormalized, and normalizes the computations.
|
||||
If you are computing the angle between two normalized vectors, it is better to use AngleBetweenNorm().
|
||||
@see AngleBetweenNorm(). */
|
||||
Angle2D AngleBetween(const Vector3& rhs) const;
|
||||
[[nodiscard]] Angle2D AngleBetween(const Vector3& rhs) const;
|
||||
static Angle2D AngleBetween(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// Adds two vectors
|
||||
Vector3 operator+(const Vector3& rhs) const;
|
||||
Vector3 Add(const Vector3& rhs) const;
|
||||
[[nodiscard]] Vector3 Add(const Vector3& rhs) const;
|
||||
static Vector3 Add(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// Adds the vector(s, s, s) to this vector
|
||||
Vector3 Add(float s) const;
|
||||
[[nodiscard]] Vector3 Add(float s) const;
|
||||
|
||||
/// Subtracts two vectors
|
||||
Vector3 operator-(const Vector3& rhs) const;
|
||||
Vector3 Sub(const Vector3& rhs) const;
|
||||
[[nodiscard]] Vector3 Sub(const Vector3& rhs) const;
|
||||
static Vector3 Sub(const Vector3& lhs, const Vector3& rhs);
|
||||
|
||||
/// Multiplies this vector by a scalar value
|
||||
Vector3 operator*(float rhs) const;
|
||||
Vector3 Mul(float scalar) const;
|
||||
[[nodiscard]] Vector3 Mul(float scalar) const;
|
||||
static Vector3 Mul(const Vector3& lhs, float rhs);
|
||||
|
||||
/// Multiplies this vector by a vector, element-wise
|
||||
/// @note Mathematically, the multiplication of two vectors is not defined in linear space structures,
|
||||
/// but this function is provided here for syntactical convenience.
|
||||
Vector3 Mul(const Vector3& rhs) const;
|
||||
[[nodiscard]] Vector3 Mul(const Vector3& rhs) const;
|
||||
|
||||
/// Divides this vector by a scalar
|
||||
Vector3 operator/(float rhs) const;
|
||||
Vector3 Div(float scalar) const;
|
||||
[[nodiscard]] Vector3 Div(float scalar) const;
|
||||
static Vector3 Div(const Vector3& lhs, float rhs);
|
||||
|
||||
/// Divides this vector by a vector, element-wise
|
||||
/// @note Mathematically, the multiplication of two vectors is not defined in linear space structures,
|
||||
/// but this function is provided here for syntactical convenience
|
||||
Vector3 Div(const Vector3& v) const;
|
||||
[[nodiscard]] Vector3 Div(const Vector3& v) const;
|
||||
|
||||
/// Unary + operator
|
||||
Vector3 operator+() const; // TODO: Implement
|
||||
/// Unary - operator (Negation)
|
||||
Vector3 operator-() const;
|
||||
|
||||
bool Equals(const Vector3& rhs, float epsilon = 1e-3f) const;
|
||||
bool Equals(float _x, float _y, float _z, float epsilon = 1e-3f) const;
|
||||
[[nodiscard]] bool Equals(const Vector3& rhs, float epsilon = 1e-3f) const;
|
||||
[[nodiscard]] bool Equals(float _x, float _y, float _z, float epsilon = 1e-3f) const;
|
||||
|
||||
Vector3 &operator =(const Vector3& rhs);
|
||||
Vector3& operator+=(const Vector3& rhs);
|
||||
@@ -340,8 +351,13 @@ public:
|
||||
|
||||
|
||||
void Set(float d, float d1, float d2);
|
||||
|
||||
|
||||
[[nodiscard]] std::string ToString() const;
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream& o, const Vector3& vector);
|
||||
|
||||
static Vector3 operator*(float lhs, const Vector3& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
|
@@ -335,6 +335,22 @@ namespace J3ML::LinearAlgebra {
|
||||
return {x, y, z};
|
||||
}
|
||||
|
||||
float Vector3::ScaleToLength(float newLength) {
|
||||
float length = LengthSquared();
|
||||
if (length < 1e-6f) {
|
||||
Set(newLength, 0, 0); // Will always produce a vector of the requested length.
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
length = Math::Sqrt(length);
|
||||
float scalar = newLength / length;
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Vector3 Vector3::Abs() const {
|
||||
return {std::abs(x), std::abs(y), std::abs(z)};
|
||||
}
|
||||
@@ -501,6 +517,15 @@ namespace J3ML::LinearAlgebra {
|
||||
z = d2;
|
||||
}
|
||||
|
||||
std::string Vector3::ToString() const {
|
||||
return std::format("{},{},{}", x, y, z);
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream &o, const Vector3 &vector) {
|
||||
o << vector.ToString();
|
||||
return o;
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Vector2& XY, float Z) {
|
||||
x = XY.x;
|
||||
y = XY.y;
|
||||
|
Reference in New Issue
Block a user