#include 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 ©) = 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 }; }