Document Vector3

This commit is contained in:
2024-04-04 21:37:12 -04:00
parent fb7aba71b1
commit b2b5fd841d
2 changed files with 116 additions and 17 deletions

View File

@@ -11,17 +11,12 @@ namespace J3ML::LinearAlgebra {
// A 3D (x, y, z) ordered pair.
class Vector3 {
public:
float x = 0;
float y = 0;
float z = 0;
public:
enum {Dimensions = 3};
// Default Constructor - Initializes to zero
Vector3();
// Constructs a new Vector3 with the value (X, Y, Z)
Vector3(float X, float Y, float Z);
Vector3(const Vector3& rhs); // Copy Constructor
Vector3(Vector3&&) = default; // Move Constructor
explicit Vector3(const float* data);
public:
static const Vector3 Zero;
static const Vector3 Up;
static const Vector3 Down;
@@ -32,8 +27,53 @@ public:
static const Vector3 NaN;
static const Vector3 Infinity;
static const Vector3 NegativeInfinity;
public:
/// The default constructor does not initialize any members of this class.
/** This means that the values of the members x, y and z are all undefined after creating a new Vector3 using
this default constructor. Remember to assign to them before use.
@see x, y, z. */
Vector3();
// Constructs a new Vector3 with the value (X, Y, Z)
Vector3(float X, float Y, float Z);
Vector3(const Vector3& rhs); // Copy Constructor
Vector3(Vector3&&) = default; // Move Constructor
/// Constructs this float3 from a C array, to the value (data[0], data[1], data[2]).
/** @param data An array containing three elements for x, y and z. This pointer may not be null. */
explicit Vector3(const float* data);
/// Constructs a new Vector3 with the value (scalar, scalar, scalar).
explicit Vector3(float scalar);
/// Casts this float3 to a C array.
/** This function does not allocate new memory or make a copy of this Vector3. This function simply
returns a C pointer view to this data structure. Use ptr()[0] to access the x component of this float3,
ptr()[1] to access y, and ptr()[2] to access the z component of this Vector3.
@note Since the returned pointer points to this class, do not dereference the pointer after this
float3 has been deleted. You should never store a copy of the returned pointer.
@note This function is provided for compatibility with other APIs which require raw C pointer access
to vectors. Avoid using this function in general, and instead always use the operator [] or
the At() function to access the elements of this vector by index.
@return A pointer to the first float element of this class. The data is contiguous in memory.
@see operator [](), At(). */
float* ptr();
[[nodiscard]] const float *ptr() const { return &x;}
/// Accesses an element of this vector using array notation.
/** @param index The element to get. Pass in 0 for x, 1 for y and 2 for z.
@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[1] = 10.f; would set the y-component of this vector.
@see ptr(), At(). */
float operator[](std::size_t index) const;
float &operator[](std::size_t index);
/// Accesses an element of this vector.
/** @param index The element to get. Pass in 0 for x, 1 for y, and 2 for z.
@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;
float &At(int index);
static void Orthonormalize(Vector3& a, Vector3& b);
@@ -61,8 +101,7 @@ public:
bool IsZero(float epsilonSq = 1e-6f) const;
bool IsPerpendicular(const Vector3& other, float epsilonSq=1e-5f) const;
float operator[](std::size_t index) const;
float &operator[](std::size_t index);
bool operator == (const Vector3& rhs) const;
bool operator != (const Vector3& rhs) const;
@@ -70,6 +109,22 @@ public:
float MinElement() const;
static float MinElement(const Vector3& of);
// Normalizes this Vector3.
/** In the case of failure, this vector is set to (1, 0, 0), so calling this function will never result in an
unnormalized vector.
@note If this function fails to normalize the vector, no error message is printed, the vector is set to (1,0,0) and
an error code 0 is returned. This is different than the behavior of the Normalized() function, which prints an
error if normalization fails.
@note This function operates in-place.
@return The old length of this vector, or 0 if normalization failed.
@see Normalized(). */
float TryNormalize();
/// 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;
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);
@@ -84,6 +139,10 @@ public:
/// Returns the magnitude between the two vectors.
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;
static float DistanceSquared(const Vector3& from, const Vector3& to);
@@ -125,14 +184,21 @@ public:
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;
static Angle2D AngleBetween(const Vector3& lhs, const Vector3& rhs);
// Adds two vectors
/// Adds two vectors
Vector3 operator+(const Vector3& rhs) const;
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;
/// Subtracts two vectors
Vector3 operator-(const Vector3& rhs) const;
Vector3 Sub(const Vector3& rhs) const;
@@ -172,10 +238,7 @@ public:
Vector3& operator-=(const Vector3& rhs);
Vector3& operator*=(float scalar);
Vector3& operator/=(float scalar);
public:
float x = 0;
float y = 0;
float z = 0;
};
static Vector3 operator*(float lhs, const Vector3& rhs)

View File

@@ -439,5 +439,41 @@ namespace J3ML::LinearAlgebra {
};
}
Vector3 Vector3::Perpendicular(const Vector3 &hint, const Vector3 &hint2) const {
assert(!this->IsZero());
assert(hint.IsNormalized());
assert(hint2.IsNormalized());
Vector3 v = this->Cross(hint);
float len = v.TryNormalize();
}
float Vector3::TryNormalize() {
assert(IsFinite());
float length = Length();
if (length > 1e-6f)
{
*this *= 1.f / length;
return length;
}
else
{
Set(1.f, 0.f, 0.f); // We will always produce a normalized vector.
return 0; // But signal failure, so user knows we have generated an arbitrary normalization.
}
}
float Vector3::At(int index) const {
assert(index >= 0);
assert(index < Dimensions);
return ptr()[index];
}
float &Vector3::At(int index) {
assert(index >= 0);
assert(index < Dimensions);
return ptr()[index];
}
}