1
0
forked from josh/j3ml
Files
j3ml-fork/include/J3ML/Vector.h
2023-12-25 13:24:33 -06:00

365 lines
11 KiB
C++

#include <LinearAlgebra/LinearAlgebra.h>
namespace LinearAlgebra {
class Vector2 {
public:
Vector2();
// Constructs a new Vector2 with the value (X, Y)
Vector2(float X, float Y);
Vector2(const Vector2 &rhs); // Copy Constructor
Vector2(Vector2 &&) = default; // Move Constructor
float GetX() const { return x; }
float GetY() const { return y; }
#if MUTABLE
void SetX(float newX) { x = newX;}
void SetY(float newY) { y = newY; }
#endif
static const Vector2 Zero;
static const Vector2 Up;
static const Vector2 Left;
static const Vector2 Down;
static const Vector2 Right;
float operator[](std::size_t index);
bool IsWithinMarginOfError(const Vector2 &rhs, float margin = 0.001f) const;
bool operator==(const Vector2 &rhs) const;
bool operator!=(const Vector2 &rhs) const;
Vector2 Min(const Vector2 &min) const;
static Vector2 Min(const Vector2 &value, const Vector2 &minimum) { return value.Min(minimum); }
Vector2 Max(const Vector2 &max) const;
static Vector2 Max(const Vector2 &value, const Vector2 &maximum) { return value.Max(maximum); }
Vector2 Clamp(const Vector2 &min, const Vector2 &max) const;
static Vector2 Clamp(const Vector2 &min, const Vector2 &middle, const Vector2 &max);
// Returns the magnitude between the two vectors.
float Distance(const Vector2 &to) const;
static float Distance(const Vector2 &from, const Vector2 &to);
float Length() const;
static float Length(const Vector2 &of) { return of.Length(); }
float LengthSquared() const;
static float LengthSquared(const Vector2 &of) { return of.LengthSquared(); }
// Returns the length of the vector, which is sqrt(x^2 + y^2)
float Magnitude() const;
static float Magnitude(const Vector2 &of) { return of.Magnitude(); }
// 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 Vector2 &rhs) const;
static float Dot(const Vector2 &lhs, const Vector2 &rhs) { return lhs.Dot(rhs); }
// Projects one vector onto another and returns the result. (IDK)
Vector2 Project(const Vector2 &rhs) const;
// @see Project
static Vector2 Project(const Vector2 &lhs, const Vector2 &rhs) { return lhs.Project(rhs); }
// Returns a copy of this vector, resized to have a magnitude of 1, while preserving "direction"
Vector2 Normalize() const;
static Vector2 Normalize(const Vector2 &of) { return of.Normalize(); }
// Linearly interpolates between two points.
// 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).
Vector2 Lerp(const Vector2 &rhs, float alpha) const;
// @see Lerp
static Vector2 Lerp(const Vector2 &lhs, const Vector2 &rhs, float alpha) { return lhs.Lerp(rhs, alpha); }
float AngleBetween(const Vector2 &rhs) const;
static float AngleBetween(const Vector2 &lhs, const Vector2 &rhs);
// Adds two vectors.
Vector2 operator+(const Vector2 &rhs) const;
Vector2 Add(const Vector2 &rhs) const;
static Vector2 Add(const Vector2 &lhs, const Vector2 &rhs);
// Subtracts two vectors.
Vector2 operator-(const Vector2 &rhs) const;
Vector2 Sub(const Vector2 &rhs) const;
static Vector2 Sub(const Vector2 &lhs, const Vector2 &rhs);
// Multiplies this vector by a scalar value.
Vector2 operator*(float rhs) const;
Vector2 Mul(float scalar) const;
static Vector2 Mul(const Vector2 &lhs, float rhs);
// Divides this vector by a scalar.
Vector2 operator/(float rhs) const;
Vector2 Div(float scalar) const;
static Vector2 Div(const Vector2 &lhs, float rhs);
// Unary operator +
Vector2 operator+() const; // TODO: Implement
Vector2 operator-() const;
// Assigns a vector to another
Vector2 &operator=(const Vector2 &v);
Vector2 &operator+=(const Vector2 &rhs); // Adds a vector to this vector, in-place.
Vector2 &operator-=(const Vector2 &rhs); // Subtracts a vector from this vector, in-place
Vector2 &operator*=(float scalar);
Vector2 &operator/=(float scalar);
public:
#if MUTABLE
float x = 0;
float y = 0;
#else
const float x = 0;
const float y = 0;
#endif
};
class Vector3 {
public:
Vector3();
Vector3(float X, float Y, float Z);
Vector3(const Vector3 &rhs);
Vector3(Vector3 &&) = default;
Vector3 &operator=(const Vector3 &rhs);
float getX() const;
float getY() const;
float getZ() const;
#if MUTABLE
void setX(float newX);
void setY(float newY);
void setZ(float newZ);
#endif
static const Vector3 Zero;
static const Vector3 Up;
static const Vector3 Down;
static const Vector3 Left;
static const Vector3 Right;
static const Vector3 Forward;
static const Vector3 Backward;
float operator[](std::size_t index) const;
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 IsFinite() const;
bool IsPerpendicular(const Vector2 &other, float epsilonSq = 1e-5f) const;
bool operator==(const Vector3 &rhs) const;
bool operator!=(const Vector3 &rhs) const;
Vector3 Min(const Vector3 &min) const;
static Vector3 Min(const Vector3 &lhs, const Vector3 &rhs);
Vector3 Max(const Vector3 &max) const;
static Vector3 Max(const Vector3 &lhs, const Vector3 &rhs);
Vector3 Clamp(const Vector3 &min, const Vector3 &max) const;
static Vector3 Clamp(const Vector3 &min, const Vector3 &input, const Vector3 &max);
float Distance(const Vector3 &to) const;
static float Distance(const Vector3 &from, const Vector3 &to);
float Length() const;
static float Length(const Vector3 &of);
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;
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;
static float Dot(const Vector3 &lhs, const Vector3 &rhs);
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;
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"
Vector3 Normalize() const;
static Vector3 Normalize(const Vector3 &targ);
// Linearly interpolates between two points.
// 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;
Vector3 operator+(const Vector3 &rhs) const;
Vector3 operator-(const Vector3 &rhs) const;
Vector3 operator*(float rhs) const;
Vector3 operator/(float rhs) const;
Vector3 operator+() const; // TODO: Implement
Vector3 operator-() const;
public:
#if MUTABLE
float x = 0;
float y = 0;
float z = 0;
#else
const float x = 0;
const float y = 0;
const float z = 0;
#endif
};
class Vector4 {
public:
Vector4();
Vector4(const Vector3 &xyz, float w = 0);
Vector4(float X, float Y, float Z, float W);
Vector4(const Vector4 &copy) = default;
Vector4(Vector4 &&move) = default;
float getX() const;
float getY() const;
float getZ() const;
float getW() const;
#if MUTABLE
void setX(float newX);
void setY(float newY);
void setZ(float newZ);
void setW(float newW);
#endif
float operator[](int index) const;
bool IsWithinMarginOfError(const Vector4 &rhs, float margin = 0.0001f) const;
bool operator==(const Vector4 &rhs) const;
bool operator!=(const Vector4 &rhs) const;
Vector4 min(const Vector4 &min) const;
Vector4 max(const Vector4 &max) const;
Vector4 clamp(const Vector4 &min, const Vector4 &max) const;
float distance(const Vector4 &to) const;
float length() const;
float lengthSquared() const;
float magnitude() const;
float dot(const Vector4 &rhs) const;
Vector4 project(const Vector4 &rhs) const;
// While it is feasable to compute a cross-product in four dimensions
// the cross product only has the orthogonality property in 3 and 7 dimensions
// You should consider instead looking at Gram-Schmidt Orthogonalization
// to find orthonormal vectors.
Vector4 cross(const Vector4 &rhs) const;
Vector4 normalize() const;
Vector4 lerp(const Vector4 &goal, float alpha) const;
Vector4 operator+(const Vector4 &rhs) const;
Vector4 operator-(const Vector4 &rhs) const;
Vector4 operator*(float rhs) const;
Vector4 operator/(float rhs) const;
Vector4 operator+() const;
Vector4 operator-() const;
public:
#if MUTABLE
float x = 0;
float y = 0;
float z = 0;
float w = 0;
#else
const float x = 0;
const float y = 0;
const float z = 0;
const float w = 0;
#endif
};
}