diff --git a/CMakeLists.txt b/CMakeLists.txt index cc49e4f..893e0f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,8 @@ file(GLOB_RECURSE J3ML_SRC "src/J3ML/*.c" "src/J3ML/*.cpp") include_directories("include") -add_library(J3ML SHARED ${J3ML_SRC}) +add_library(J3ML SHARED ${J3ML_SRC} + src/J3ML/LinearAlgebra/AxisAngle.cpp) set_target_properties(J3ML PROPERTIES LINKER_LANGUAGE CXX) install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME}) diff --git a/include/J3ML/LinearAlgebra/AxisAngle.h b/include/J3ML/LinearAlgebra/AxisAngle.h index b885157..89580f7 100644 --- a/include/J3ML/LinearAlgebra/AxisAngle.h +++ b/include/J3ML/LinearAlgebra/AxisAngle.h @@ -11,7 +11,6 @@ namespace LinearAlgebra class AxisAngle { Vector3 axis; float angle; - public: AxisAngle(); AxisAngle(const Vector3& axis, float angle); diff --git a/include/J3ML/LinearAlgebra/Vector2.h b/include/J3ML/LinearAlgebra/Vector2.h index f9c7cfd..d65bd6e 100644 --- a/include/J3ML/LinearAlgebra/Vector2.h +++ b/include/J3ML/LinearAlgebra/Vector2.h @@ -1,12 +1,8 @@ - #pragma once - #include #include - namespace LinearAlgebra { - // A 2D (x, y) ordered pair. class Vector2 { public: @@ -16,12 +12,7 @@ namespace LinearAlgebra { Vector2(float X, float Y); Vector2(const Vector2& rhs); // Copy Constructor Vector2(Vector2&&) = default; // Move Constructor - float GetX() const; - float GetY() const; -#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; @@ -29,16 +20,18 @@ namespace LinearAlgebra { static const Vector2 Right; static const Vector2 NaN; - float operator[](std::size_t index); + float GetX() const; + float GetY() const; + void SetX(float newX); + void SetY(float newY); bool IsWithinMarginOfError(const Vector2& 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; - + float operator[](std::size_t index); bool operator == (const Vector2& rhs) const; bool operator != (const Vector2& rhs) const; @@ -125,12 +118,8 @@ namespace LinearAlgebra { Vector2& operator/=(float scalar); public: -#if MUTABLE float x = 0; float y = 0; -#else - float x = 0; - float y = 0; -#endif + }; } \ No newline at end of file diff --git a/include/J3ML/LinearAlgebra/Vector3.h b/include/J3ML/LinearAlgebra/Vector3.h index 540abe5..3385faa 100644 --- a/include/J3ML/LinearAlgebra/Vector3.h +++ b/include/J3ML/LinearAlgebra/Vector3.h @@ -2,6 +2,7 @@ #include #include +#include namespace LinearAlgebra { @@ -18,14 +19,7 @@ public: Vector3(Vector3&&) = default; // Move Constructor Vector3& operator=(const Vector3& rhs); - float GetX() const; - float GetY() const; - float GetZ() const; -#if MUTABLE - void SetX(float newX) { x = newX;} - void SetY(float newY) { y = newY;} - void SetZ(float newZ) { z = newZ;} -#endif + static const Vector3 Zero; static const Vector3 Up; static const Vector3 Down; @@ -35,15 +29,21 @@ public: static const Vector3 Backward; static const Vector3 NaN; - float operator[](std::size_t index) const; + float GetX() const; + float GetY() const; + 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 IsFinite() const; bool IsPerpendicular(const Vector3& other, float epsilonSq=1e-5f) const; + float operator[](std::size_t index) const; bool operator == (const Vector3& rhs) const; bool operator != (const Vector3& rhs) const; @@ -68,7 +68,10 @@ public: // Returns the length of the vector, which is sqrt(x^2 + y^2 + z^2) float Magnitude() const; - static float Magnitude(const Vector3& of); + 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, @@ -127,14 +130,9 @@ public: public: -#if MUTABLE - float x = 0; - float y = 0; - float z = 0; -#else float x = 0; float y = 0; float z = 0; -#endif + }; } \ No newline at end of file diff --git a/src/J3ML/LinearAlgebra/AxisAngle.cpp b/src/J3ML/LinearAlgebra/AxisAngle.cpp new file mode 100644 index 0000000..b0b3492 --- /dev/null +++ b/src/J3ML/LinearAlgebra/AxisAngle.cpp @@ -0,0 +1,8 @@ +#include + +namespace LinearAlgebra { + + AxisAngle::AxisAngle() : axis(Vector3::Zero) {} + + AxisAngle::AxisAngle(const Vector3 &axis, float angle) : axis(axis), angle(angle) {} +} \ No newline at end of file diff --git a/src/J3ML/LinearAlgebra/Matrix4x4.cpp b/src/J3ML/LinearAlgebra/Matrix4x4.cpp index 50ff365..3be5e12 100644 --- a/src/J3ML/LinearAlgebra/Matrix4x4.cpp +++ b/src/J3ML/LinearAlgebra/Matrix4x4.cpp @@ -1 +1,5 @@ -#include \ No newline at end of file +#include + +namespace LinearAlgebra { + +} \ No newline at end of file diff --git a/src/J3ML/LinearAlgebra/Vector2.cpp b/src/J3ML/LinearAlgebra/Vector2.cpp index bd32981..62b0a41 100644 --- a/src/J3ML/LinearAlgebra/Vector2.cpp +++ b/src/J3ML/LinearAlgebra/Vector2.cpp @@ -5,160 +5,159 @@ namespace LinearAlgebra { + Vector2::Vector2(): x(0), y(0) + {} -Vector2::Vector2(): x(0), y(0) -{} + Vector2::Vector2(float X, float Y): x(X), y(Y) + {} -Vector2::Vector2(float X, float Y): x(X), y(Y) -{} + Vector2::Vector2(const Vector2& rhs): x(rhs.x), y(rhs.y) + {} -Vector2::Vector2(const Vector2& rhs): x(rhs.x), y(rhs.y) -{} + float Vector2::operator[](std::size_t index) + { + assert(index < 2); + if (index == 0) return x; + if (index == 1) return y; + return 0; + } -float Vector2::operator[](std::size_t index) -{ - assert(index < 2); - if (index == 0) return x; - if (index == 1) return y; - return 0; -} + bool Vector2::IsWithinMarginOfError(const Vector2& rhs, float margin) const + { + return this->Distance(rhs) <= margin; + } -bool Vector2::IsWithinMarginOfError(const Vector2& rhs, float margin) const -{ - return this->Distance(rhs) <= margin; -} + bool Vector2::operator==(const Vector2& rhs) const + { + return this->IsWithinMarginOfError(rhs); + } -bool Vector2::operator==(const Vector2& rhs) const -{ - return this->IsWithinMarginOfError(rhs); -} + bool Vector2::operator!=(const Vector2& rhs) const + { + return this->IsWithinMarginOfError(rhs) == false; + } -bool Vector2::operator!=(const Vector2& rhs) const -{ - return this->IsWithinMarginOfError(rhs) == false; -} - -Vector2 Vector2::Min(const Vector2& min) const -{ - return { - std::min(this->x, min.x), - std::min(this->y, min.y) - }; -} - -Vector2 Vector2::Max(const Vector2& max) const -{ - return { - std::max(this->x, max.x), - std::max(this->y, max.y) - }; -} - -Vector2 Vector2::Clamp(const Vector2& min, const Vector2& max) const -{ - return { - std::clamp(this->x, min.x, max.x), - std::clamp(this->y, min.y, max.y) - }; -} - -float Vector2::Distance(const Vector2& to) const -{ - return ((*this)-to).Magnitude(); -} - -float Vector2::Length() const -{ - return std::sqrt(LengthSquared()); -} - -float Vector2::LengthSquared() const -{ - return (x*x + y*y); -} - -float Vector2::Magnitude() const -{ - return std::sqrt(LengthSquared()); -} - -float Vector2::Dot(const Vector2& rhs) const -{ - auto a = this->Normalize(); - auto b = rhs.Normalize(); - - return a.x * b.x + a.y * b.y; -} - -Vector2 Vector2::Project(const Vector2& rhs) const -{ - float scalar = this->Dot(rhs) / (rhs.Magnitude()*rhs.Magnitude()); - return rhs * scalar; -} - -Vector2 Vector2::Normalize() const -{ - if (Length() > 0) + Vector2 Vector2::Min(const Vector2& min) const + { return { - x / Length(), - y / Length() + std::min(this->x, min.x), + std::min(this->y, min.y) }; - else - return {0,0}; -} + } -Vector2 Vector2::Lerp(const Vector2& rhs, float alpha) const -{ - return this->operator*(1.0f - alpha) + (rhs * alpha); -} + Vector2 Vector2::Max(const Vector2& max) const + { + return { + std::max(this->x, max.x), + std::max(this->y, max.y) + }; + } -float Vector2::AngleBetween(const Vector2& rhs) const -{ - auto numer = this->Dot(rhs); - auto denom = this->Magnitude() * rhs.Magnitude(); - return std::acos(numer / denom); -} + Vector2 Vector2::Clamp(const Vector2& min, const Vector2& max) const + { + return { + std::clamp(this->x, min.x, max.x), + std::clamp(this->y, min.y, max.y) + }; + } -float Vector2::AngleBetween(const Vector2& lhs, const Vector2& rhs) -{ return lhs.AngleBetween(rhs); } + float Vector2::Distance(const Vector2& to) const + { + return ((*this)-to).Magnitude(); + } -Vector2 Vector2::operator+(const Vector2& rhs) const -{ - return {this->x + rhs.x, this->y + rhs.y}; -} + float Vector2::Length() const + { + return std::sqrt(LengthSquared()); + } -Vector2 Vector2::operator-(const Vector2& rhs) const -{ - return {this->x - rhs.x, this->y - rhs.y}; -} + float Vector2::LengthSquared() const + { + return (x*x + y*y); + } -Vector2 Vector2::operator*(float rhs) const -{ - return { - this->x * rhs, - this->y * rhs - }; -} + float Vector2::Magnitude() const + { + return std::sqrt(LengthSquared()); + } -Vector2 Vector2::operator/(float rhs) const -{ - return { - this->x / rhs, - this->y / rhs - }; -} + float Vector2::Dot(const Vector2& rhs) const + { + auto a = this->Normalize(); + auto b = rhs.Normalize(); -Vector2 Vector2::operator-() const -{ - return {-x, -y}; -} + return a.x * b.x + a.y * b.y; + } -const Vector2 Vector2::Zero = {0, 0}; -const Vector2 Vector2::Up = {0, -1}; -const Vector2 Vector2::Down = {0, 1}; -const Vector2 Vector2::Left = {-1, 0}; -const Vector2 Vector2::Right = {1, 0}; -const Vector2 Vector2::NaN = {NAN, NAN}; + Vector2 Vector2::Project(const Vector2& rhs) const + { + float scalar = this->Dot(rhs) / (rhs.Magnitude()*rhs.Magnitude()); + return rhs * scalar; + } + + Vector2 Vector2::Normalize() const + { + if (Length() > 0) + return { + x / Length(), + y / Length() + }; + else + return {0,0}; + } + + Vector2 Vector2::Lerp(const Vector2& rhs, float alpha) const + { + return this->operator*(1.0f - alpha) + (rhs * alpha); + } + + float Vector2::AngleBetween(const Vector2& rhs) const + { + auto numer = this->Dot(rhs); + auto denom = this->Magnitude() * rhs.Magnitude(); + return std::acos(numer / denom); + } + + float Vector2::AngleBetween(const Vector2& lhs, const Vector2& rhs) + { return lhs.AngleBetween(rhs); } + + Vector2 Vector2::operator+(const Vector2& rhs) const + { + return {this->x + rhs.x, this->y + rhs.y}; + } + + Vector2 Vector2::operator-(const Vector2& rhs) const + { + return {this->x - rhs.x, this->y - rhs.y}; + } + + Vector2 Vector2::operator*(float rhs) const + { + return { + this->x * rhs, + this->y * rhs + }; + } + + Vector2 Vector2::operator/(float rhs) const + { + return { + this->x / rhs, + this->y / rhs + }; + } + + Vector2 Vector2::operator-() const + { + return {-x, -y}; + } + + const Vector2 Vector2::Zero = {0, 0}; + const Vector2 Vector2::Up = {0, -1}; + const Vector2 Vector2::Down = {0, 1}; + const Vector2 Vector2::Left = {-1, 0}; + const Vector2 Vector2::Right = {1, 0}; + const Vector2 Vector2::NaN = {NAN, NAN}; float Vector2::GetX() const { return x; } @@ -172,5 +171,22 @@ const Vector2 Vector2::NaN = {NAN, NAN}; float Vector2::Length(const Vector2 &of) { return of.Length(); } + void Vector2::SetX(float newX) { x = newX;} + + void Vector2::SetY(float newY) { y = newY; } + + bool Vector2::IsNormalized(float epsilonSq) const { + return std::abs(LengthSquared() - 1.f) <= epsilonSq; + } + + bool Vector2::IsZero(float epsilonSq) const { + return LengthSquared() <= epsilonSq; + } + + bool Vector2::IsPerpendicular(const Vector2 &other, float epsilonSq) const { + float dot = Dot(other); + return dot*dot <= epsilonSq * LengthSquared() * other.LengthSquared(); + } + } \ No newline at end of file diff --git a/src/J3ML/LinearAlgebra/Vector3.cpp b/src/J3ML/LinearAlgebra/Vector3.cpp index 3373fa3..f10d519 100644 --- a/src/J3ML/LinearAlgebra/Vector3.cpp +++ b/src/J3ML/LinearAlgebra/Vector3.cpp @@ -188,5 +188,48 @@ namespace LinearAlgebra { float Vector3::GetZ() const { return z;} + void Vector3::SetX(float newX) { x = newX;} + + void Vector3::SetY(float newY) { y = newY;} + + void Vector3::SetZ(float newZ) { z = newZ;} + + Vector3 Vector3::Min(const Vector3 &lhs, const Vector3 &rhs) { + return lhs.Min(rhs); + } + + Vector3 Vector3::Max(const Vector3 &lhs, const Vector3 &rhs) { + return lhs.Max(rhs); + } + + Vector3 Vector3::Clamp(const Vector3 &min, const Vector3 &input, const Vector3 &max) { + return input.Clamp(min, max); + } + + float Vector3::Distance(const Vector3 &from, const Vector3 &to) { + return from.Distance(to); + } + + float Vector3::Length(const Vector3 &of) { + return of.Length(); + } + + float Vector3::LengthSquared(const Vector3 &of) { + return of.LengthSquared(); + } + + bool Vector3::IsPerpendicular(const Vector3 &other, float epsilonSq) const { + float dot = Dot(other); + return dot*dot <= epsilonSq * LengthSquared() * other.LengthSquared(); + } + + bool Vector3::IsZero(float epsilonSq) const { + return LengthSquared() <= epsilonSq; + } + + bool Vector3::IsNormalized(float epsilonSq) const { + return std::abs(LengthSquared()-1.f) <= epsilonSq; + } + #pragma endregion } \ No newline at end of file diff --git a/tests/LinearAlgebra/Vector3Tests.cpp b/tests/LinearAlgebra/Vector3Tests.cpp index a8cec1d..37460f7 100644 --- a/tests/LinearAlgebra/Vector3Tests.cpp +++ b/tests/LinearAlgebra/Vector3Tests.cpp @@ -1,3 +1,9 @@ -// -// Created by josh on 12/26/2023. -// +#include +#include + +using Vector3 = LinearAlgebra::Vector3; + +TEST(Vector3Test, V3_Constructor_Default) +{ + +} \ No newline at end of file