From 690097559af10d8fb63795d2ecc156931c7a8821 Mon Sep 17 00:00:00 2001 From: YuanSang <142496327+YuanSang0512@users.noreply.github.com> Date: Wed, 15 Apr 2026 22:55:12 +0800 Subject: [PATCH 1/4] =?UTF-8?q?Develop=20vector2=E3=80=81constants=20and?= =?UTF-8?q?=20scalar.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/gkit/math/constants.hpp | 89 +++++++++++++++++++++++++ include/gkit/math/scalar.hpp | 57 ++++++++++++++++ include/gkit/math/vector2.hpp | 74 ++++++++++++++------- src/math/vector2.cpp | 10 +-- test/math/test_math.cpp | 88 ++++++++++++++++++++++++ test/math/test_vector2.cpp | 114 ++++++++++++++++++++++++++++---- 6 files changed, 391 insertions(+), 41 deletions(-) create mode 100644 include/gkit/math/constants.hpp create mode 100644 include/gkit/math/scalar.hpp create mode 100644 test/math/test_math.cpp diff --git a/include/gkit/math/constants.hpp b/include/gkit/math/constants.hpp new file mode 100644 index 0000000..7844911 --- /dev/null +++ b/include/gkit/math/constants.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include + +#include "gkit/math/scalar.hpp" + +namespace gkit::math { + // Mathematical constants (IEEE 754 standard) + namespace math_const { + // Pi multiples + constexpr float32 PI_32 = std::numbers::pi_v; + constexpr float32 TWO_PI_32 = PI_32 * 2.0f; + constexpr float32 HALF_PI_32 = PI_32 * 0.5f; + constexpr float32 INV_PI_32 = std::numbers::inv_pi_v; + + constexpr float64 PI_64 = std::numbers::pi; + constexpr float64 TWO_PI_64 = PI_64 * 2.0; + constexpr float64 HALF_PI_64 = PI_64 * 0.5; + constexpr float64 INV_PI_64 = std::numbers::inv_pi; + + // Natural constants + constexpr float32 E_32 = std::numbers::e_v; + constexpr float64 E_64 = std::numbers::e; + + // Golden ratio + constexpr float32 PHI_32 = std::numbers::phi_v; + constexpr float64 PHI_64 = std::numbers::phi; + + // Powers and roots + constexpr float32 SQRT_2_32 = std::numbers::sqrt2_v; + constexpr float32 SQRT_3_32 = std::numbers::sqrt3_v; + constexpr float32 SQRT_5_32 = 2.2360679774997897f; // sqrt(5) + constexpr float32 LN_2_32 = std::numbers::ln2_v; + constexpr float32 LN_10_32 = std::numbers::ln10_v; + + constexpr float64 SQRT_2_64 = std::numbers::sqrt2; + constexpr float64 SQRT_3_64 = std::numbers::sqrt3; + constexpr float64 SQRT_5_64 = 2.2360679774997896964091736687313; // sqrt(5) + constexpr float64 LN_2_64 = std::numbers::ln2; + constexpr float64 LN_10_64 = std::numbers::ln10; + } // namespace math_const + + // Angle conversion constants + namespace angle_const { + constexpr float32 DEG_TO_RAD_32 = gkit::math::math_const::PI_32 / 180.0f; + constexpr float32 RAD_TO_DEG_32 = 180.0f / gkit::math::math_const::PI_32; + + constexpr float64 DEG_TO_RAD_64 = gkit::math::math_const::PI_64 / 180.0; + constexpr float64 RAD_TO_DEG_64 = 180.0 / gkit::math::math_const::PI_64; + } // namespace angle_const + + // Common numeric constants + namespace numeric_const { + constexpr float32 ZERO_32 = 0.0f; + constexpr float32 ONE_32 = 1.0f; + constexpr float32 NEG_ONE_32 = -1.0f; + constexpr float32 TWO_32 = 2.0f; + constexpr float32 THREE_32 = 3.0f; + constexpr float32 FOUR_32 = 4.0f; + constexpr float32 FIVE_32 = 5.0f; + constexpr float32 TEN_32 = 10.0f; + constexpr float32 HUNDRED_32 = 100.0f; + constexpr float32 THOUSAND_32 = 1000.0f; + constexpr float32 HALF_32 = 0.5f; + constexpr float32 QUARTER_32 = 0.25f; + constexpr float32 THIRD_32 = 0.3333333333333333333333333333333f; + + constexpr float64 ZERO_64 = 0.0; + constexpr float64 ONE_64 = 1.0; + constexpr float64 NEG_ONE_64 = -1.0; + constexpr float64 TWO_64 = 2.0; + constexpr float64 THREE_64 = 3.0; + constexpr float64 FOUR_64 = 4.0; + constexpr float64 FIVE_64 = 5.0; + constexpr float64 TEN_64 = 10.0; + constexpr float64 HUNDRED_64 = 100.0; + constexpr float64 THOUSAND_64 = 1000.0; + constexpr float64 HALF_64 = 0.5; + constexpr float64 QUARTER_64 = 0.25; + constexpr float64 THIRD_64 = 0.3333333333333333333333333333333; + + // Integers + constexpr int32 ZERO_I32 = 0; + constexpr int32 ONE_I32 = 1; + constexpr int32 NEG_ONE_I32 = -1; + constexpr int32 TWO_I32 = 2; + constexpr int32 THREE_I32 = 3; + } // namespace numeric_const +} // namespace gkit::math \ No newline at end of file diff --git a/include/gkit/math/scalar.hpp b/include/gkit/math/scalar.hpp new file mode 100644 index 0000000..8770dab --- /dev/null +++ b/include/gkit/math/scalar.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +namespace gkit::math { + // Basic scalar type aliases + using int8 = int8_t; + using int16 = int16_t; + using int32 = int32_t; + using int64 = int64_t; + using uint8 = uint8_t; + using uint16 = uint16_t; + using uint32 = uint32_t; + using uint64 = uint64_t; + using float32 = float; + using float64 = double; + + // Common limits for scalar types + template + struct ScalarLimits { + static constexpr T min_v = std::numeric_limits::min(); + static constexpr T max_v = std::numeric_limits::max(); + static constexpr T lowest_v = std::numeric_limits::lowest(); + static constexpr T epsilon_v = std::numeric_limits::epsilon(); + }; + + // Floating-point special values + namespace fp { + constexpr float32 EPSILON32 = 1.1920928955078125e-07f; // FLT_EPSILON + constexpr float32 MIN32 = 1.1754943508222875e-38f; // FLT_MIN + constexpr float32 MAX32 = 3.4028234663852886e+38f; // FLT_MAX + + constexpr float64 EPSILON64 = 2.2204460492503131e-16; // DBL_EPSILON + constexpr float64 MIN64 = 2.2250738585072014e-308; // DBL_MIN + constexpr float64 MAX64 = 1.7976931348623157e+308; // DBL_MAX + } // namespace fp + + // Integer special values + namespace int_limits { + constexpr int8 I8_MIN = -128; + constexpr int8 I8_MAX = 127; + constexpr uint8 U8_MAX = 255; + + constexpr int16 I16_MIN = -32768; + constexpr int16 I16_MAX = 32767; + constexpr uint16 U16_MAX = 65535; + + constexpr int32 I32_MIN = -2147483647 - 1; + constexpr int32 I32_MAX = 2147483647; + constexpr uint32 U32_MAX = 4294967295u; + + constexpr int64 I64_MIN = -9223372036854775807ll - 1; + constexpr int64 I64_MAX = 9223372036854775807ll; + constexpr uint64 U64_MAX = 18446744073709551615ull; + } // namespace int_limits +} // namespace gkit::math \ No newline at end of file diff --git a/include/gkit/math/vector2.hpp b/include/gkit/math/vector2.hpp index 76e2640..e710da9 100644 --- a/include/gkit/math/vector2.hpp +++ b/include/gkit/math/vector2.hpp @@ -1,44 +1,72 @@ #pragma once +#include "gkit/math/scalar.hpp" + #include -#include #include + namespace gkit::math { class Vector2 final { public: + float32 x = 0.0f; + float32 y = 0.0f; + Vector2() noexcept = default; - Vector2(float x, float y) noexcept; + explicit Vector2(float32 v) noexcept; + Vector2(float32 x, float32 y) noexcept; Vector2(const Vector2& other) noexcept; Vector2(const Vector2&& other) noexcept; ~Vector2() noexcept = default; - public: // Arithmetic operators - inline auto operator= (const Vector2& other) noexcept -> Vector2& { this->x = other.x; this->y = other.y; return *this; } - inline auto operator= (const Vector2&&other) noexcept -> Vector2& { this->x = other.x; this->y = other.y; return *this; } + public: // Arithmetic operators + inline auto operator=(const Vector2& other) noexcept -> Vector2& { this->x = other.x; this->y = other.y; return *this; } + inline auto operator=(const Vector2&& other) noexcept -> Vector2& { this->x = other.x; this->y = other.y; return *this; } inline auto operator==(const Vector2& other) noexcept -> bool { return this->x == other.x && this->y == other.y; } inline auto operator!=(const Vector2& other) noexcept -> bool { return this->x != other.x || this->y != other.y; } - inline auto operator+ (const Vector2& other) noexcept -> Vector2 { return Vector2(this->x + other.x, this->y + other.y); } - inline auto operator- (const Vector2& other) noexcept -> Vector2 { return Vector2(this->x - other.x, this->y - other.y); } + inline auto operator+(const Vector2& other) noexcept -> Vector2 { return Vector2(this->x + other.x, this->y + other.y); } + inline auto operator-(const Vector2& other) noexcept -> Vector2 { return Vector2(this->x - other.x, this->y - other.y); } inline auto operator+=(const Vector2& other) noexcept -> const Vector2& { this->x += other.x; this->y += other.y; return *this; } inline auto operator-=(const Vector2& other) noexcept -> const Vector2& { this->x -= other.x; this->y -= other.y; return *this; } - inline auto operator* (const int32_t n) noexcept -> Vector2 { return Vector2(this->x * n, this->y * n); } - inline auto operator/ (const int32_t n) noexcept -> Vector2 { return Vector2(this->x / n, this->y / n); } - inline auto operator*=(const int32_t n) noexcept -> const Vector2& { this->x *= n; this->y *= n; return *this; } - inline auto operator/=(const int32_t n) noexcept -> const Vector2& { this->x /= n; this->y /= n; return *this; } + inline auto operator*(float32 s) noexcept -> Vector2 { return Vector2(this->x * s, this->y * s); } + inline auto operator/(float32 s) noexcept -> Vector2 { return Vector2(this->x / s, this->y / s); } + inline auto operator*=(float32 s) noexcept -> const Vector2& { this->x *= s; this->y *= s; return *this; } + inline auto operator/=(float32 s) noexcept -> const Vector2& { this->x /= s; this->y /= s; return *this; } + inline auto operator-() noexcept -> Vector2 { return Vector2(-this->x, -this->y); } - public: + public: // Properties static auto zero() -> const Vector2&; auto normalization() -> void; -#ifdef _MSC_VER - inline auto length() const -> float { return std::sqrt(x * x + y * y); } -#else - inline constexpr auto length() const -> float { return std::sqrt(x * x + y * y); } -#endif - inline auto properties() -> auto { return std::tie(x, y);} - - private: - float x = 0.f, - y = 0.f; + + inline constexpr auto length() const -> float32 { return std::sqrt(x * x + y * y); } + inline constexpr auto length_sq() const -> float32 { return x * x + y * y; } + inline auto properties() -> auto { return std::tie(x, y); } + + public: // Operations + static inline auto dot(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.x + a.y * b.y; } + static inline auto cross(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.y - a.y * b.x; } + static inline auto normalize(const Vector2& v) noexcept -> Vector2 { + float32 len = v.length(); + return (len > 0.0f) ? Vector2{v.x / len, v.y / len} : Vector2{0.0f, 0.0f}; + } + static inline auto lerp(const Vector2& a, const Vector2& b, float32 t) noexcept -> Vector2 { + return {a.x + t * (b.x - a.x), a.y + t * (b.y - a.y)}; + } + static inline auto min(const Vector2& a, const Vector2& b) noexcept -> Vector2 { + return {(a.x < b.x) ? a.x : b.x, (a.y < b.y) ? a.y : b.y}; + } + static inline auto max(const Vector2& a, const Vector2& b) noexcept -> Vector2 { + return {(a.x > b.x) ? a.x : b.x, (a.y > b.y) ? a.y : b.y}; + } + static inline auto perp(const Vector2& v) noexcept -> Vector2 { return {-v.y, v.x}; } + static inline auto reflect(const Vector2& v, const Vector2& n) noexcept -> Vector2 { + float32 d = 2.0f * dot(v, n); + return {v.x - d * n.x, v.y - d * n.y}; + } + static inline auto distance(const Vector2& a, const Vector2& b) noexcept -> float32 { + float32 dx = b.x - a.x; + float32 dy = b.y - a.y; + return std::sqrt(dx * dx + dy * dy); + } }; // class Vector2 -} // namespace math +} // namespace gkit::math \ No newline at end of file diff --git a/src/math/vector2.cpp b/src/math/vector2.cpp index 94646aa..bad9fd6 100644 --- a/src/math/vector2.cpp +++ b/src/math/vector2.cpp @@ -1,18 +1,18 @@ -#include +#include "gkit/math/vector2.hpp" - -gkit::math::Vector2::Vector2(float x, float y) noexcept : x(x), y(y) { } +gkit::math::Vector2::Vector2(float32 v) noexcept : x(v), y(v) { } +gkit::math::Vector2::Vector2(float32 x, float32 y) noexcept : x(x), y(y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2& other) noexcept : x(other.x), y(other.y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2&& other) noexcept : x(other.x), y(other.y) { } auto gkit::math::Vector2::normalization() -> void { auto len = this->length(); - this->x /= len; this->y /= len; + x /= len; y /= len; } auto gkit::math::Vector2::zero() -> const Vector2& { static Vector2 zero = Vector2(0.0f, 0.0f); return zero; -} +} \ No newline at end of file diff --git a/test/math/test_math.cpp b/test/math/test_math.cpp new file mode 100644 index 0000000..e008a12 --- /dev/null +++ b/test/math/test_math.cpp @@ -0,0 +1,88 @@ +#include +#include +#include "gkit/math/constants.hpp" +#include "gkit/math/scalar.hpp" + +using namespace gkit::math; + +int main() { + // ====== test scalar.hpp ====== + + // Type alias tests + static_assert(sizeof(gkit::math::int8) == 1, "int8 size error"); + static_assert(sizeof(gkit::math::int16) == 2, "int16 size error"); + static_assert(sizeof(gkit::math::int32) == 4, "int32 size error"); + static_assert(sizeof(gkit::math::int64) == 8, "int64 size error"); + static_assert(sizeof(gkit::math::uint8) == 1, "uint8 size error"); + static_assert(sizeof(gkit::math::uint16) == 2, "uint16 size error"); + static_assert(sizeof(gkit::math::uint32) == 4, "uint32 size error"); + static_assert(sizeof(gkit::math::uint64) == 8, "uint64 size error"); + static_assert(sizeof(gkit::math::float32) == 4, "float32 size error"); + static_assert(sizeof(gkit::math::float64) == 8, "float64 size error"); + + // ScalarLimits tests + assert(ScalarLimits::min_v == -2147483647 - 1); + assert(ScalarLimits::max_v == 2147483647); + assert(ScalarLimits::epsilon_v > 0); + + // fp constants tests + assert(fp::EPSILON32 > 0); + assert(fp::MIN32 > 0); + assert(fp::MAX32 > fp::MIN32); + + // integer constants tests + assert(int_limits::I8_MIN == -128); + assert(int_limits::I8_MAX == 127); + assert(int_limits::U8_MAX == 255); + assert(int_limits::I16_MIN == -32768); + assert(int_limits::I16_MAX == 32767); + assert(int_limits::U16_MAX == 65535); + + // ====== Test constants.hpp ====== + + // Math constants tests + assert(gkit::math::math_const::PI_32 > 3.14f && gkit::math::math_const::PI_32 < 3.15f); + assert(gkit::math::math_const::TWO_PI_32 > 6.28f && gkit::math::math_const::TWO_PI_32 < 6.29f); + assert(gkit::math::math_const::HALF_PI_32 > 1.57f && gkit::math::math_const::HALF_PI_32 < 1.58f); + assert(gkit::math::math_const::INV_PI_32 > 0.31f && gkit::math::math_const::INV_PI_32 < 0.32f); + assert(gkit::math::math_const::E_32 > 2.71f && gkit::math::math_const::E_32 < 2.72f); + assert(gkit::math::math_const::PHI_32 > 1.61f && gkit::math::math_const::PHI_32 < 1.62f); + assert(gkit::math::math_const::SQRT_2_32 > 1.41f && gkit::math::math_const::SQRT_2_32 < 1.42f); + assert(gkit::math::math_const::LN_2_32 > 0.69f && gkit::math::math_const::LN_2_32 < 0.70f); + + // Angle conversion tests + assert(gkit::math::angle_const::DEG_TO_RAD_32 > 0.017f && gkit::math::angle_const::DEG_TO_RAD_32 < 0.018f); + assert(gkit::math::angle_const::RAD_TO_DEG_32 > 57.2f && gkit::math::angle_const::RAD_TO_DEG_32 < 57.3f); + + // Numeric constants tests + assert(gkit::math::numeric_const::ZERO_32 == 0.0f); + assert(gkit::math::numeric_const::ONE_32 == 1.0f); + assert(gkit::math::numeric_const::NEG_ONE_32 == -1.0f); + assert(gkit::math::numeric_const::TWO_32 == 2.0f); + assert(gkit::math::numeric_const::HALF_32 == 0.5f); + assert(gkit::math::numeric_const::QUARTER_32 == 0.25f); + + assert(gkit::math::numeric_const::ZERO_I32 == 0); + assert(gkit::math::numeric_const::ONE_I32 == 1); + assert(gkit::math::numeric_const::NEG_ONE_I32 == -1); + assert(gkit::math::numeric_const::TWO_I32 == 2); + + // Print test output + printf("=== scalar.hpp tests ===\n"); + printf("int32 min: %d, max: %d\n", + gkit::math::ScalarLimits::min_v, + gkit::math::ScalarLimits::max_v); + printf("float32 epsilon: %.10f\n", gkit::math::ScalarLimits::epsilon_v); + + printf("\n=== constants.hpp tests ===\n"); + printf("PI_32: %.10f\n", gkit::math::math_const::PI_32); + printf("TWO_PI_32: %.10f\n", gkit::math::math_const::TWO_PI_32); + printf("E_32: %.10f\n", gkit::math::math_const::E_32); + printf("PHI_32: %.10f\n", gkit::math::math_const::PHI_32); + printf("SQRT_2_32: %.10f\n", gkit::math::math_const::SQRT_2_32); + printf("DEG_TO_RAD_32: %.10f\n", gkit::math::angle_const::DEG_TO_RAD_32); + printf("RAD_TO_DEG_32: %.10f\n", gkit::math::angle_const::RAD_TO_DEG_32); + + printf("\nAll tests passed!\n"); + return 0; +} \ No newline at end of file diff --git a/test/math/test_vector2.cpp b/test/math/test_vector2.cpp index 19f4842..71b35d8 100644 --- a/test/math/test_vector2.cpp +++ b/test/math/test_vector2.cpp @@ -1,32 +1,120 @@ -#include +#include "gkit/math/vector2.hpp" +#include "gkit/math/scalar.hpp" + +#include +#include #include #include #include + using gkit::math::Vector2; -auto vec_str(Vector2& vec) -> std::string { - auto [x, y] = vec.properties(); - return std::format("x = {}, y = {}", x, y); +auto vec_str(const Vector2& vec) -> std::string { + return std::format("x = {:.4f}, y = {:.4f}", vec.x, vec.y); } auto main() -> int { + // Basic constructors Vector2 vec1(1.0f, 2.0f); std::cout << "vec1: " << vec_str(vec1) << std::endl; + + // Fill constructor + Vector2 vec_fill(5.0f); + assert(vec_fill.x == 5.0f && vec_fill.y == 5.0f); + std::cout << "vec_fill (Vector2(5.0f)): " << vec_str(vec_fill) << std::endl; + Vector2 vec2(3.0f, 4.0f); std::cout << "vec2: " << vec_str(vec2) << std::endl; - Vector2 vec3 = vec1 + vec2; - std::cout << "vec1 + vec2: " << vec_str(vec3) << std::endl; - Vector2 vec4 = vec1 - vec2; - std::cout << "vec1 - vec2: " << vec_str(vec4) << std::endl; - Vector2 vec5 = vec1 * 10; - std::cout << "vec1 * 10: " << vec_str(vec5) << std::endl; - Vector2 vec6 = vec1 / 10; - std::cout << "vec1 / 10: " << vec_str(vec6) << std::endl; + // Arithmetic operators + Vector2 vec_add = vec1 + vec2; + std::cout << "vec1 + vec2: " << vec_str(vec_add) << std::endl; + assert(vec_add.x == 4.0f && vec_add.y == 6.0f); + + Vector2 vec_sub = vec1 - vec2; + std::cout << "vec1 - vec2: " << vec_str(vec_sub) << std::endl; + assert(vec_sub.x == -2.0f && vec_sub.y == -2.0f); + + Vector2 vec_mul = vec1 * 10.0f; + std::cout << "vec1 * 10: " << vec_str(vec_mul) << std::endl; + assert(vec_mul.x == 10.0f && vec_mul.y == 20.0f); + Vector2 vec_div = vec1 / 10.0f; + std::cout << "vec1 / 10: " << vec_str(vec_div) << std::endl; + assert(std::abs(vec_div.x - 0.1f) < gkit::math::fp::EPSILON32 && std::abs(vec_div.y - 0.2f) < gkit::math::fp::EPSILON32); + + // Length std::cout << "vec1.length(): " << vec1.length() << std::endl; + assert(std::abs(vec1.length() - std::sqrt(5.0f)) < gkit::math::fp::EPSILON32); + + // Length squared + std::cout << "vec1.length_sq(): " << vec1.length_sq() << std::endl; + assert(std::abs(vec1.length_sq() - 5.0f) < gkit::math::fp::EPSILON32); + + // Normalization (instance method) vec1.normalization(); std::cout << "vec1.normalization(): " << vec_str(vec1) << std::endl; - std::cout << "vec1.length() after normalization(): " << vec1.length() << std::endl; + assert(std::abs(vec1.length() - 1.0f) < gkit::math::fp::EPSILON32); + + // Reset for further tests + Vector2 a(1.0f, 0.0f); + Vector2 b(0.0f, 1.0f); + + // Dot product + gkit::math::float32 dot_result = Vector2::dot(a, b); + std::cout << "Vector2::dot(a, b): " << dot_result << std::endl; + assert(dot_result == 0.0f); + + gkit::math::float32 dot_a = Vector2::dot(a, a); + assert(dot_a == 1.0f); + + // Cross product + gkit::math::float32 cross_result = Vector2::cross(a, b); + std::cout << "Vector2::cross(a, b): " << cross_result << std::endl; + assert(cross_result == 1.0f); + + // Normalize (static) + Vector2 c(3.0f, 4.0f); + Vector2 c_normalized = Vector2::normalize(c); + std::cout << "Vector2::normalize(3,4): " << vec_str(c_normalized) << std::endl; + assert(std::abs(c_normalized.length() - 1.0f) < gkit::math::fp::EPSILON32); + + // Lerp + Vector2 lerp_result = Vector2::lerp(a, b, 0.5f); + std::cout << "Vector2::lerp((1,0), (0,1), 0.5): " << vec_str(lerp_result) << std::endl; + assert(std::abs(lerp_result.x - 0.5f) < gkit::math::fp::EPSILON32); + assert(std::abs(lerp_result.y - 0.5f) < gkit::math::fp::EPSILON32); + + // Min / Max + Vector2 min_result = Vector2::min(a, b); + std::cout << "Vector2::min((1,0), (0,1)): " << vec_str(min_result) << std::endl; + assert(min_result.x == 0.0f && min_result.y == 0.0f); + + Vector2 max_result = Vector2::max(a, b); + std::cout << "Vector2::max((1,0), (0,1)): " << vec_str(max_result) << std::endl; + assert(max_result.x == 1.0f && max_result.y == 1.0f); + + // Perp + Vector2 perp_result = Vector2::perp(a); + std::cout << "Vector2::perp((1,0)): " << vec_str(perp_result) << std::endl; + assert(perp_result.x == 0.0f && perp_result.y == 1.0f); + + // Reflect + Vector2 v(1.0f, 1.0f); + Vector2 n(0.0f, 1.0f); // Reflect off horizontal surface + Vector2 reflect_result = Vector2::reflect(v, n); + std::cout << "Vector2::reflect((1,1), (0,1)): " << vec_str(reflect_result) << std::endl; + assert(std::abs(reflect_result.x - 1.0f) < gkit::math::fp::EPSILON32); + assert(std::abs(reflect_result.y - (-1.0f)) < gkit::math::fp::EPSILON32); + + // Distance + Vector2 p1(0.0f, 0.0f); + Vector2 p2(3.0f, 4.0f); + gkit::math::float32 dist = Vector2::distance(p1, p2); + std::cout << "Vector2::distance((0,0), (3,4)): " << dist << std::endl; + assert(std::abs(dist - 5.0f) < gkit::math::fp::EPSILON32); + + std::cout << "\nAll tests passed!" << std::endl; + return 0; } \ No newline at end of file From 7642a894b6431dc237106b15a24ef7cff6e408f8 Mon Sep 17 00:00:00 2001 From: YuanSang <142496327+YuanSang0512@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:04:42 +0800 Subject: [PATCH 2/4] Use the standard limits lib instead of hardcoding for scalar types; Fix some small problems. --- include/gkit/math/scalar.hpp | 40 +++++++++++++++++------------------ include/gkit/math/vector2.hpp | 17 ++++++++------- src/math/vector2.cpp | 12 ----------- test/math/test_vector2.cpp | 6 +++--- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/include/gkit/math/scalar.hpp b/include/gkit/math/scalar.hpp index 8770dab..a8a0a82 100644 --- a/include/gkit/math/scalar.hpp +++ b/include/gkit/math/scalar.hpp @@ -25,33 +25,33 @@ namespace gkit::math { static constexpr T epsilon_v = std::numeric_limits::epsilon(); }; - // Floating-point special values + // Floating-point special values using numeric_limits namespace fp { - constexpr float32 EPSILON32 = 1.1920928955078125e-07f; // FLT_EPSILON - constexpr float32 MIN32 = 1.1754943508222875e-38f; // FLT_MIN - constexpr float32 MAX32 = 3.4028234663852886e+38f; // FLT_MAX + constexpr float32 EPSILON32 = std::numeric_limits::epsilon(); + constexpr float32 MIN32 = std::numeric_limits::min(); + constexpr float32 MAX32 = std::numeric_limits::max(); - constexpr float64 EPSILON64 = 2.2204460492503131e-16; // DBL_EPSILON - constexpr float64 MIN64 = 2.2250738585072014e-308; // DBL_MIN - constexpr float64 MAX64 = 1.7976931348623157e+308; // DBL_MAX + constexpr float64 EPSILON64 = std::numeric_limits::epsilon(); + constexpr float64 MIN64 = std::numeric_limits::min(); + constexpr float64 MAX64 = std::numeric_limits::max(); } // namespace fp - // Integer special values + // Integer special values using numeric_limits namespace int_limits { - constexpr int8 I8_MIN = -128; - constexpr int8 I8_MAX = 127; - constexpr uint8 U8_MAX = 255; + constexpr int8 I8_MIN = std::numeric_limits::min(); + constexpr int8 I8_MAX = std::numeric_limits::max(); + constexpr uint8 U8_MAX = std::numeric_limits::max(); - constexpr int16 I16_MIN = -32768; - constexpr int16 I16_MAX = 32767; - constexpr uint16 U16_MAX = 65535; + constexpr int16 I16_MIN = std::numeric_limits::min(); + constexpr int16 I16_MAX = std::numeric_limits::max(); + constexpr uint16 U16_MAX = std::numeric_limits::max(); - constexpr int32 I32_MIN = -2147483647 - 1; - constexpr int32 I32_MAX = 2147483647; - constexpr uint32 U32_MAX = 4294967295u; + constexpr int32 I32_MIN = std::numeric_limits::min(); + constexpr int32 I32_MAX = std::numeric_limits::max(); + constexpr uint32 U32_MAX = std::numeric_limits::max(); - constexpr int64 I64_MIN = -9223372036854775807ll - 1; - constexpr int64 I64_MAX = 9223372036854775807ll; - constexpr uint64 U64_MAX = 18446744073709551615ull; + constexpr int64 I64_MIN = std::numeric_limits::min(); + constexpr int64 I64_MAX = std::numeric_limits::max(); + constexpr uint64 U64_MAX = std::numeric_limits::max(); } // namespace int_limits } // namespace gkit::math \ No newline at end of file diff --git a/include/gkit/math/vector2.hpp b/include/gkit/math/vector2.hpp index e710da9..e9cd4a6 100644 --- a/include/gkit/math/vector2.hpp +++ b/include/gkit/math/vector2.hpp @@ -28,21 +28,22 @@ namespace gkit::math { inline auto operator-(const Vector2& other) noexcept -> Vector2 { return Vector2(this->x - other.x, this->y - other.y); } inline auto operator+=(const Vector2& other) noexcept -> const Vector2& { this->x += other.x; this->y += other.y; return *this; } inline auto operator-=(const Vector2& other) noexcept -> const Vector2& { this->x -= other.x; this->y -= other.y; return *this; } - inline auto operator*(float32 s) noexcept -> Vector2 { return Vector2(this->x * s, this->y * s); } - inline auto operator/(float32 s) noexcept -> Vector2 { return Vector2(this->x / s, this->y / s); } + inline auto operator*(float32 s) noexcept -> Vector2 { return {this->x * s, this->y * s}; } + inline auto operator/(float32 s) noexcept -> Vector2 { return {this->x / s, this->y / s}; } inline auto operator*=(float32 s) noexcept -> const Vector2& { this->x *= s; this->y *= s; return *this; } inline auto operator/=(float32 s) noexcept -> const Vector2& { this->x /= s; this->y /= s; return *this; } - inline auto operator-() noexcept -> Vector2 { return Vector2(-this->x, -this->y); } + inline auto operator-() noexcept -> Vector2 { return {-this->x, -this->y}; } public: // Properties - static auto zero() -> const Vector2&; - auto normalization() -> void; - - inline constexpr auto length() const -> float32 { return std::sqrt(x * x + y * y); } - inline constexpr auto length_sq() const -> float32 { return x * x + y * y; } + [[nodiscard]] inline auto length() const -> float32 { return std::sqrt(x * x + y * y); } + [[nodiscard]] inline constexpr auto length_sq() const -> float32 { return x * x + y * y; } inline auto properties() -> auto { return std::tie(x, y); } public: // Operations + inline static auto zero() noexcept -> Vector2 { return {0.0f, 0.0f}; } + inline static auto one() noexcept -> Vector2 { return {1.0f, 1.0f}; } + + static inline auto dot(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.x + a.y * b.y; } static inline auto cross(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.y - a.y * b.x; } static inline auto normalize(const Vector2& v) noexcept -> Vector2 { diff --git a/src/math/vector2.cpp b/src/math/vector2.cpp index bad9fd6..373ac9f 100644 --- a/src/math/vector2.cpp +++ b/src/math/vector2.cpp @@ -4,15 +4,3 @@ gkit::math::Vector2::Vector2(float32 v) noexcept : x(v), y(v) { } gkit::math::Vector2::Vector2(float32 x, float32 y) noexcept : x(x), y(y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2& other) noexcept : x(other.x), y(other.y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2&& other) noexcept : x(other.x), y(other.y) { } - - -auto gkit::math::Vector2::normalization() -> void { - auto len = this->length(); - x /= len; y /= len; -} - - -auto gkit::math::Vector2::zero() -> const Vector2& { - static Vector2 zero = Vector2(0.0f, 0.0f); - return zero; -} \ No newline at end of file diff --git a/test/math/test_vector2.cpp b/test/math/test_vector2.cpp index 71b35d8..fb16bb9 100644 --- a/test/math/test_vector2.cpp +++ b/test/math/test_vector2.cpp @@ -52,9 +52,9 @@ auto main() -> int { std::cout << "vec1.length_sq(): " << vec1.length_sq() << std::endl; assert(std::abs(vec1.length_sq() - 5.0f) < gkit::math::fp::EPSILON32); - // Normalization (instance method) - vec1.normalization(); - std::cout << "vec1.normalization(): " << vec_str(vec1) << std::endl; + // Normalization + vec1 = Vector2::normalize(vec1); + std::cout << "vec1 after normalize: " << vec_str(vec1) << std::endl; assert(std::abs(vec1.length() - 1.0f) < gkit::math::fp::EPSILON32); // Reset for further tests From 54718a4358eebeae5639b53fd64c060bde3b5b03 Mon Sep 17 00:00:00 2001 From: YuanSang <142496327+YuanSang0512@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:33:20 +0800 Subject: [PATCH 3/4] Remove unnecessary math namespace; --- include/gkit/math/constants.hpp | 132 +++++++++++++++----------------- include/gkit/math/scalar.hpp | 48 +++++------- include/gkit/math/vector2.hpp | 38 +++++---- src/math/vector2.cpp | 4 +- test/math/test_math.cpp | 78 ++++++++----------- test/math/test_vector2.cpp | 8 +- 6 files changed, 137 insertions(+), 171 deletions(-) diff --git a/include/gkit/math/constants.hpp b/include/gkit/math/constants.hpp index 7844911..fc42868 100644 --- a/include/gkit/math/constants.hpp +++ b/include/gkit/math/constants.hpp @@ -2,88 +2,80 @@ #include -#include "gkit/math/scalar.hpp" - namespace gkit::math { // Mathematical constants (IEEE 754 standard) - namespace math_const { - // Pi multiples - constexpr float32 PI_32 = std::numbers::pi_v; - constexpr float32 TWO_PI_32 = PI_32 * 2.0f; - constexpr float32 HALF_PI_32 = PI_32 * 0.5f; - constexpr float32 INV_PI_32 = std::numbers::inv_pi_v; + // Pi multiples + constexpr float PI_32 = std::numbers::pi_v; + constexpr float TWO_PI_32 = PI_32 * 2.0f; + constexpr float HALF_PI_32 = PI_32 * 0.5f; + constexpr float INV_PI_32 = std::numbers::inv_pi_v; - constexpr float64 PI_64 = std::numbers::pi; - constexpr float64 TWO_PI_64 = PI_64 * 2.0; - constexpr float64 HALF_PI_64 = PI_64 * 0.5; - constexpr float64 INV_PI_64 = std::numbers::inv_pi; + constexpr float PI_64 = std::numbers::pi; + constexpr float TWO_PI_64 = PI_64 * 2.0; + constexpr float HALF_PI_64 = PI_64 * 0.5; + constexpr float INV_PI_64 = std::numbers::inv_pi; - // Natural constants - constexpr float32 E_32 = std::numbers::e_v; - constexpr float64 E_64 = std::numbers::e; + // Natural constants + constexpr float E_32 = std::numbers::e_v; + constexpr float E_64 = std::numbers::e; - // Golden ratio - constexpr float32 PHI_32 = std::numbers::phi_v; - constexpr float64 PHI_64 = std::numbers::phi; + // Golden ratio + constexpr float PHI_32 = std::numbers::phi_v; + constexpr float PHI_64 = std::numbers::phi; - // Powers and roots - constexpr float32 SQRT_2_32 = std::numbers::sqrt2_v; - constexpr float32 SQRT_3_32 = std::numbers::sqrt3_v; - constexpr float32 SQRT_5_32 = 2.2360679774997897f; // sqrt(5) - constexpr float32 LN_2_32 = std::numbers::ln2_v; - constexpr float32 LN_10_32 = std::numbers::ln10_v; + // Powers and roots + constexpr float SQRT_2_32 = std::numbers::sqrt2_v; + constexpr float SQRT_3_32 = std::numbers::sqrt3_v; + constexpr float SQRT_5_32 = 2.2360679774997897f; // sqrt(5) + constexpr float LN_2_32 = std::numbers::ln2_v; + constexpr float LN_10_32 = std::numbers::ln10_v; - constexpr float64 SQRT_2_64 = std::numbers::sqrt2; - constexpr float64 SQRT_3_64 = std::numbers::sqrt3; - constexpr float64 SQRT_5_64 = 2.2360679774997896964091736687313; // sqrt(5) - constexpr float64 LN_2_64 = std::numbers::ln2; - constexpr float64 LN_10_64 = std::numbers::ln10; - } // namespace math_const + constexpr float SQRT_2_64 = std::numbers::sqrt2; + constexpr float SQRT_3_64 = std::numbers::sqrt3; + constexpr float SQRT_5_64 = 2.2360679774997896964091736687313; // sqrt(5) + constexpr float LN_2_64 = std::numbers::ln2; + constexpr float LN_10_64 = std::numbers::ln10; // Angle conversion constants - namespace angle_const { - constexpr float32 DEG_TO_RAD_32 = gkit::math::math_const::PI_32 / 180.0f; - constexpr float32 RAD_TO_DEG_32 = 180.0f / gkit::math::math_const::PI_32; + constexpr float DEG_TO_RAD_32 = gkit::math::PI_32 / 180.0f; + constexpr float RAD_TO_DEG_32 = 180.0f / gkit::math::PI_32; - constexpr float64 DEG_TO_RAD_64 = gkit::math::math_const::PI_64 / 180.0; - constexpr float64 RAD_TO_DEG_64 = 180.0 / gkit::math::math_const::PI_64; - } // namespace angle_const + constexpr float DEG_TO_RAD_64 = gkit::math::PI_64 / 180.0; + constexpr float RAD_TO_DEG_64 = 180.0 / gkit::math::PI_64; // Common numeric constants - namespace numeric_const { - constexpr float32 ZERO_32 = 0.0f; - constexpr float32 ONE_32 = 1.0f; - constexpr float32 NEG_ONE_32 = -1.0f; - constexpr float32 TWO_32 = 2.0f; - constexpr float32 THREE_32 = 3.0f; - constexpr float32 FOUR_32 = 4.0f; - constexpr float32 FIVE_32 = 5.0f; - constexpr float32 TEN_32 = 10.0f; - constexpr float32 HUNDRED_32 = 100.0f; - constexpr float32 THOUSAND_32 = 1000.0f; - constexpr float32 HALF_32 = 0.5f; - constexpr float32 QUARTER_32 = 0.25f; - constexpr float32 THIRD_32 = 0.3333333333333333333333333333333f; + constexpr float ZERO_32 = 0.0f; + constexpr float ONE_32 = 1.0f; + constexpr float NEG_ONE_32 = -1.0f; + constexpr float TWO_32 = 2.0f; + constexpr float THREE_32 = 3.0f; + constexpr float FOUR_32 = 4.0f; + constexpr float FIVE_32 = 5.0f; + constexpr float TEN_32 = 10.0f; + constexpr float HUNDRED_32 = 100.0f; + constexpr float THOUSAND_32 = 1000.0f; + constexpr float HALF_32 = 0.5f; + constexpr float QUARTER_32 = 0.25f; + constexpr float THIRD_32 = 0.3333333333333333333333333333333f; - constexpr float64 ZERO_64 = 0.0; - constexpr float64 ONE_64 = 1.0; - constexpr float64 NEG_ONE_64 = -1.0; - constexpr float64 TWO_64 = 2.0; - constexpr float64 THREE_64 = 3.0; - constexpr float64 FOUR_64 = 4.0; - constexpr float64 FIVE_64 = 5.0; - constexpr float64 TEN_64 = 10.0; - constexpr float64 HUNDRED_64 = 100.0; - constexpr float64 THOUSAND_64 = 1000.0; - constexpr float64 HALF_64 = 0.5; - constexpr float64 QUARTER_64 = 0.25; - constexpr float64 THIRD_64 = 0.3333333333333333333333333333333; + constexpr float ZERO_64 = 0.0; + constexpr float ONE_64 = 1.0; + constexpr float NEG_ONE_64 = -1.0; + constexpr float TWO_64 = 2.0; + constexpr float THREE_64 = 3.0; + constexpr float FOUR_64 = 4.0; + constexpr float FIVE_64 = 5.0; + constexpr float TEN_64 = 10.0; + constexpr float HUNDRED_64 = 100.0; + constexpr float THOUSAND_64 = 1000.0; + constexpr float HALF_64 = 0.5; + constexpr float QUARTER_64 = 0.25; + constexpr float THIRD_64 = 0.3333333333333333333333333333333; - // Integers - constexpr int32 ZERO_I32 = 0; - constexpr int32 ONE_I32 = 1; - constexpr int32 NEG_ONE_I32 = -1; - constexpr int32 TWO_I32 = 2; - constexpr int32 THREE_I32 = 3; - } // namespace numeric_const + // Integers + constexpr int ZERO_I32 = 0; + constexpr int ONE_I32 = 1; + constexpr int NEG_ONE_I32 = -1; + constexpr int TWO_I32 = 2; + constexpr int THREE_I32 = 3; } // namespace gkit::math \ No newline at end of file diff --git a/include/gkit/math/scalar.hpp b/include/gkit/math/scalar.hpp index a8a0a82..cef37ff 100644 --- a/include/gkit/math/scalar.hpp +++ b/include/gkit/math/scalar.hpp @@ -4,18 +4,6 @@ #include namespace gkit::math { - // Basic scalar type aliases - using int8 = int8_t; - using int16 = int16_t; - using int32 = int32_t; - using int64 = int64_t; - using uint8 = uint8_t; - using uint16 = uint16_t; - using uint32 = uint32_t; - using uint64 = uint64_t; - using float32 = float; - using float64 = double; - // Common limits for scalar types template struct ScalarLimits { @@ -27,31 +15,31 @@ namespace gkit::math { // Floating-point special values using numeric_limits namespace fp { - constexpr float32 EPSILON32 = std::numeric_limits::epsilon(); - constexpr float32 MIN32 = std::numeric_limits::min(); - constexpr float32 MAX32 = std::numeric_limits::max(); + constexpr float EPSILON32 = std::numeric_limits::epsilon(); + constexpr float MIN32 = std::numeric_limits::min(); + constexpr float MAX32 = std::numeric_limits::max(); - constexpr float64 EPSILON64 = std::numeric_limits::epsilon(); - constexpr float64 MIN64 = std::numeric_limits::min(); - constexpr float64 MAX64 = std::numeric_limits::max(); + constexpr float EPSILON64 = std::numeric_limits::epsilon(); + constexpr float MIN64 = std::numeric_limits::min(); + constexpr float MAX64 = std::numeric_limits::max(); } // namespace fp // Integer special values using numeric_limits namespace int_limits { - constexpr int8 I8_MIN = std::numeric_limits::min(); - constexpr int8 I8_MAX = std::numeric_limits::max(); - constexpr uint8 U8_MAX = std::numeric_limits::max(); + constexpr int8_t I8_MIN = std::numeric_limits::min(); + constexpr int8_t I8_MAX = std::numeric_limits::max(); + constexpr uint8_t U8_MAX = std::numeric_limits::max(); - constexpr int16 I16_MIN = std::numeric_limits::min(); - constexpr int16 I16_MAX = std::numeric_limits::max(); - constexpr uint16 U16_MAX = std::numeric_limits::max(); + constexpr int16_t I16_MIN = std::numeric_limits::min(); + constexpr int16_t I16_MAX = std::numeric_limits::max(); + constexpr uint16_t U16_MAX = std::numeric_limits::max(); - constexpr int32 I32_MIN = std::numeric_limits::min(); - constexpr int32 I32_MAX = std::numeric_limits::max(); - constexpr uint32 U32_MAX = std::numeric_limits::max(); + constexpr int32_t I32_MIN = std::numeric_limits::min(); + constexpr int32_t I32_MAX = std::numeric_limits::max(); + constexpr uint32_t U32_MAX = std::numeric_limits::max(); - constexpr int64 I64_MIN = std::numeric_limits::min(); - constexpr int64 I64_MAX = std::numeric_limits::max(); - constexpr uint64 U64_MAX = std::numeric_limits::max(); + constexpr int64_t I64_MIN = std::numeric_limits::min(); + constexpr int64_t I64_MAX = std::numeric_limits::max(); + constexpr uint64_t U64_MAX = std::numeric_limits::max(); } // namespace int_limits } // namespace gkit::math \ No newline at end of file diff --git a/include/gkit/math/vector2.hpp b/include/gkit/math/vector2.hpp index e9cd4a6..81d4a9e 100644 --- a/include/gkit/math/vector2.hpp +++ b/include/gkit/math/vector2.hpp @@ -1,7 +1,5 @@ #pragma once -#include "gkit/math/scalar.hpp" - #include #include @@ -9,12 +7,12 @@ namespace gkit::math { class Vector2 final { public: - float32 x = 0.0f; - float32 y = 0.0f; + float x = 0.0f; + float y = 0.0f; Vector2() noexcept = default; - explicit Vector2(float32 v) noexcept; - Vector2(float32 x, float32 y) noexcept; + explicit Vector2(float v) noexcept; + Vector2(float x, float y) noexcept; Vector2(const Vector2& other) noexcept; Vector2(const Vector2&& other) noexcept; ~Vector2() noexcept = default; @@ -28,15 +26,15 @@ namespace gkit::math { inline auto operator-(const Vector2& other) noexcept -> Vector2 { return Vector2(this->x - other.x, this->y - other.y); } inline auto operator+=(const Vector2& other) noexcept -> const Vector2& { this->x += other.x; this->y += other.y; return *this; } inline auto operator-=(const Vector2& other) noexcept -> const Vector2& { this->x -= other.x; this->y -= other.y; return *this; } - inline auto operator*(float32 s) noexcept -> Vector2 { return {this->x * s, this->y * s}; } - inline auto operator/(float32 s) noexcept -> Vector2 { return {this->x / s, this->y / s}; } - inline auto operator*=(float32 s) noexcept -> const Vector2& { this->x *= s; this->y *= s; return *this; } - inline auto operator/=(float32 s) noexcept -> const Vector2& { this->x /= s; this->y /= s; return *this; } + inline auto operator*(float s) noexcept -> Vector2 { return {this->x * s, this->y * s}; } + inline auto operator/(float s) noexcept -> Vector2 { return {this->x / s, this->y / s}; } + inline auto operator*=(float s) noexcept -> const Vector2& { this->x *= s; this->y *= s; return *this; } + inline auto operator/=(float s) noexcept -> const Vector2& { this->x /= s; this->y /= s; return *this; } inline auto operator-() noexcept -> Vector2 { return {-this->x, -this->y}; } public: // Properties - [[nodiscard]] inline auto length() const -> float32 { return std::sqrt(x * x + y * y); } - [[nodiscard]] inline constexpr auto length_sq() const -> float32 { return x * x + y * y; } + [[nodiscard]] inline auto length() const -> float { return std::sqrt(x * x + y * y); } + [[nodiscard]] inline constexpr auto length_sq() const -> float { return x * x + y * y; } inline auto properties() -> auto { return std::tie(x, y); } public: // Operations @@ -44,13 +42,13 @@ namespace gkit::math { inline static auto one() noexcept -> Vector2 { return {1.0f, 1.0f}; } - static inline auto dot(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.x + a.y * b.y; } - static inline auto cross(const Vector2& a, const Vector2& b) noexcept -> float32 { return a.x * b.y - a.y * b.x; } + static inline auto dot(const Vector2& a, const Vector2& b) noexcept -> float { return a.x * b.x + a.y * b.y; } + static inline auto cross(const Vector2& a, const Vector2& b) noexcept -> float { return a.x * b.y - a.y * b.x; } static inline auto normalize(const Vector2& v) noexcept -> Vector2 { - float32 len = v.length(); + float len = v.length(); return (len > 0.0f) ? Vector2{v.x / len, v.y / len} : Vector2{0.0f, 0.0f}; } - static inline auto lerp(const Vector2& a, const Vector2& b, float32 t) noexcept -> Vector2 { + static inline auto lerp(const Vector2& a, const Vector2& b, float t) noexcept -> Vector2 { return {a.x + t * (b.x - a.x), a.y + t * (b.y - a.y)}; } static inline auto min(const Vector2& a, const Vector2& b) noexcept -> Vector2 { @@ -61,12 +59,12 @@ namespace gkit::math { } static inline auto perp(const Vector2& v) noexcept -> Vector2 { return {-v.y, v.x}; } static inline auto reflect(const Vector2& v, const Vector2& n) noexcept -> Vector2 { - float32 d = 2.0f * dot(v, n); + float d = 2.0f * dot(v, n); return {v.x - d * n.x, v.y - d * n.y}; } - static inline auto distance(const Vector2& a, const Vector2& b) noexcept -> float32 { - float32 dx = b.x - a.x; - float32 dy = b.y - a.y; + static inline auto distance(const Vector2& a, const Vector2& b) noexcept -> float { + float dx = b.x - a.x; + float dy = b.y - a.y; return std::sqrt(dx * dx + dy * dy); } }; // class Vector2 diff --git a/src/math/vector2.cpp b/src/math/vector2.cpp index 373ac9f..c50c559 100644 --- a/src/math/vector2.cpp +++ b/src/math/vector2.cpp @@ -1,6 +1,6 @@ #include "gkit/math/vector2.hpp" -gkit::math::Vector2::Vector2(float32 v) noexcept : x(v), y(v) { } -gkit::math::Vector2::Vector2(float32 x, float32 y) noexcept : x(x), y(y) { } +gkit::math::Vector2::Vector2(float v) noexcept : x(v), y(v) { } +gkit::math::Vector2::Vector2(float x, float y) noexcept : x(x), y(y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2& other) noexcept : x(other.x), y(other.y) { } gkit::math::Vector2::Vector2(const gkit::math::Vector2&& other) noexcept : x(other.x), y(other.y) { } diff --git a/test/math/test_math.cpp b/test/math/test_math.cpp index e008a12..0ff474f 100644 --- a/test/math/test_math.cpp +++ b/test/math/test_math.cpp @@ -8,22 +8,10 @@ using namespace gkit::math; int main() { // ====== test scalar.hpp ====== - // Type alias tests - static_assert(sizeof(gkit::math::int8) == 1, "int8 size error"); - static_assert(sizeof(gkit::math::int16) == 2, "int16 size error"); - static_assert(sizeof(gkit::math::int32) == 4, "int32 size error"); - static_assert(sizeof(gkit::math::int64) == 8, "int64 size error"); - static_assert(sizeof(gkit::math::uint8) == 1, "uint8 size error"); - static_assert(sizeof(gkit::math::uint16) == 2, "uint16 size error"); - static_assert(sizeof(gkit::math::uint32) == 4, "uint32 size error"); - static_assert(sizeof(gkit::math::uint64) == 8, "uint64 size error"); - static_assert(sizeof(gkit::math::float32) == 4, "float32 size error"); - static_assert(sizeof(gkit::math::float64) == 8, "float64 size error"); - // ScalarLimits tests - assert(ScalarLimits::min_v == -2147483647 - 1); - assert(ScalarLimits::max_v == 2147483647); - assert(ScalarLimits::epsilon_v > 0); + assert(ScalarLimits::min_v == -2147483647 - 1); + assert(ScalarLimits::max_v == 2147483647); + assert(ScalarLimits::epsilon_v > 0); // fp constants tests assert(fp::EPSILON32 > 0); @@ -41,47 +29,47 @@ int main() { // ====== Test constants.hpp ====== // Math constants tests - assert(gkit::math::math_const::PI_32 > 3.14f && gkit::math::math_const::PI_32 < 3.15f); - assert(gkit::math::math_const::TWO_PI_32 > 6.28f && gkit::math::math_const::TWO_PI_32 < 6.29f); - assert(gkit::math::math_const::HALF_PI_32 > 1.57f && gkit::math::math_const::HALF_PI_32 < 1.58f); - assert(gkit::math::math_const::INV_PI_32 > 0.31f && gkit::math::math_const::INV_PI_32 < 0.32f); - assert(gkit::math::math_const::E_32 > 2.71f && gkit::math::math_const::E_32 < 2.72f); - assert(gkit::math::math_const::PHI_32 > 1.61f && gkit::math::math_const::PHI_32 < 1.62f); - assert(gkit::math::math_const::SQRT_2_32 > 1.41f && gkit::math::math_const::SQRT_2_32 < 1.42f); - assert(gkit::math::math_const::LN_2_32 > 0.69f && gkit::math::math_const::LN_2_32 < 0.70f); + assert(gkit::math::PI_32 > 3.14f && gkit::math::PI_32 < 3.15f); + assert(gkit::math::TWO_PI_32 > 6.28f && gkit::math::TWO_PI_32 < 6.29f); + assert(gkit::math::HALF_PI_32 > 1.57f && gkit::math::HALF_PI_32 < 1.58f); + assert(gkit::math::INV_PI_32 > 0.31f && gkit::math::INV_PI_32 < 0.32f); + assert(gkit::math::E_32 > 2.71f && gkit::math::E_32 < 2.72f); + assert(gkit::math::PHI_32 > 1.61f && gkit::math::PHI_32 < 1.62f); + assert(gkit::math::SQRT_2_32 > 1.41f && gkit::math::SQRT_2_32 < 1.42f); + assert(gkit::math::LN_2_32 > 0.69f && gkit::math::LN_2_32 < 0.70f); // Angle conversion tests - assert(gkit::math::angle_const::DEG_TO_RAD_32 > 0.017f && gkit::math::angle_const::DEG_TO_RAD_32 < 0.018f); - assert(gkit::math::angle_const::RAD_TO_DEG_32 > 57.2f && gkit::math::angle_const::RAD_TO_DEG_32 < 57.3f); + assert(gkit::math::DEG_TO_RAD_32 > 0.017f && gkit::math::DEG_TO_RAD_32 < 0.018f); + assert(gkit::math::RAD_TO_DEG_32 > 57.2f && gkit::math::RAD_TO_DEG_32 < 57.3f); // Numeric constants tests - assert(gkit::math::numeric_const::ZERO_32 == 0.0f); - assert(gkit::math::numeric_const::ONE_32 == 1.0f); - assert(gkit::math::numeric_const::NEG_ONE_32 == -1.0f); - assert(gkit::math::numeric_const::TWO_32 == 2.0f); - assert(gkit::math::numeric_const::HALF_32 == 0.5f); - assert(gkit::math::numeric_const::QUARTER_32 == 0.25f); + assert(gkit::math::ZERO_32 == 0.0f); + assert(gkit::math::ONE_32 == 1.0f); + assert(gkit::math::NEG_ONE_32 == -1.0f); + assert(gkit::math::TWO_32 == 2.0f); + assert(gkit::math::HALF_32 == 0.5f); + assert(gkit::math::QUARTER_32 == 0.25f); - assert(gkit::math::numeric_const::ZERO_I32 == 0); - assert(gkit::math::numeric_const::ONE_I32 == 1); - assert(gkit::math::numeric_const::NEG_ONE_I32 == -1); - assert(gkit::math::numeric_const::TWO_I32 == 2); + assert(gkit::math::ZERO_I32 == 0); + assert(gkit::math::ONE_I32 == 1); + assert(gkit::math::NEG_ONE_I32 == -1); + assert(gkit::math::TWO_I32 == 2); // Print test output printf("=== scalar.hpp tests ===\n"); printf("int32 min: %d, max: %d\n", - gkit::math::ScalarLimits::min_v, - gkit::math::ScalarLimits::max_v); - printf("float32 epsilon: %.10f\n", gkit::math::ScalarLimits::epsilon_v); + gkit::math::ScalarLimits::min_v, + gkit::math::ScalarLimits::max_v); + printf("float32 epsilon: %.10f\n", gkit::math::ScalarLimits::epsilon_v); printf("\n=== constants.hpp tests ===\n"); - printf("PI_32: %.10f\n", gkit::math::math_const::PI_32); - printf("TWO_PI_32: %.10f\n", gkit::math::math_const::TWO_PI_32); - printf("E_32: %.10f\n", gkit::math::math_const::E_32); - printf("PHI_32: %.10f\n", gkit::math::math_const::PHI_32); - printf("SQRT_2_32: %.10f\n", gkit::math::math_const::SQRT_2_32); - printf("DEG_TO_RAD_32: %.10f\n", gkit::math::angle_const::DEG_TO_RAD_32); - printf("RAD_TO_DEG_32: %.10f\n", gkit::math::angle_const::RAD_TO_DEG_32); + printf("PI_32: %.10f\n", gkit::math::PI_32); + printf("TWO_PI_32: %.10f\n", gkit::math::TWO_PI_32); + printf("E_32: %.10f\n", gkit::math::E_32); + printf("PHI_32: %.10f\n", gkit::math::PHI_32); + printf("SQRT_2_32: %.10f\n", gkit::math::SQRT_2_32); + printf("DEG_TO_RAD_32: %.10f\n", gkit::math::DEG_TO_RAD_32); + printf("RAD_TO_DEG_32: %.10f\n", gkit::math::RAD_TO_DEG_32); printf("\nAll tests passed!\n"); return 0; diff --git a/test/math/test_vector2.cpp b/test/math/test_vector2.cpp index fb16bb9..b37eda2 100644 --- a/test/math/test_vector2.cpp +++ b/test/math/test_vector2.cpp @@ -62,15 +62,15 @@ auto main() -> int { Vector2 b(0.0f, 1.0f); // Dot product - gkit::math::float32 dot_result = Vector2::dot(a, b); + float dot_result = Vector2::dot(a, b); std::cout << "Vector2::dot(a, b): " << dot_result << std::endl; assert(dot_result == 0.0f); - gkit::math::float32 dot_a = Vector2::dot(a, a); + float dot_a = Vector2::dot(a, a); assert(dot_a == 1.0f); // Cross product - gkit::math::float32 cross_result = Vector2::cross(a, b); + float cross_result = Vector2::cross(a, b); std::cout << "Vector2::cross(a, b): " << cross_result << std::endl; assert(cross_result == 1.0f); @@ -111,7 +111,7 @@ auto main() -> int { // Distance Vector2 p1(0.0f, 0.0f); Vector2 p2(3.0f, 4.0f); - gkit::math::float32 dist = Vector2::distance(p1, p2); + float dist = Vector2::distance(p1, p2); std::cout << "Vector2::distance((0,0), (3,4)): " << dist << std::endl; assert(std::abs(dist - 5.0f) < gkit::math::fp::EPSILON32); From 282d15ae30e5550fa9dc06801922b35f2ed3a870 Mon Sep 17 00:00:00 2001 From: YuanSang <142496327+YuanSang0512@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:58:06 +0800 Subject: [PATCH 4/4] Remove unnecessary math namespace --- include/gkit/math/scalar.hpp | 46 ++++++++++++++++-------------------- test/math/test_math.cpp | 18 +++++++------- test/math/test_vector2.cpp | 20 ++++++++-------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/include/gkit/math/scalar.hpp b/include/gkit/math/scalar.hpp index cef37ff..e75217a 100644 --- a/include/gkit/math/scalar.hpp +++ b/include/gkit/math/scalar.hpp @@ -14,32 +14,28 @@ namespace gkit::math { }; // Floating-point special values using numeric_limits - namespace fp { - constexpr float EPSILON32 = std::numeric_limits::epsilon(); - constexpr float MIN32 = std::numeric_limits::min(); - constexpr float MAX32 = std::numeric_limits::max(); + constexpr float EPSILON32 = std::numeric_limits::epsilon(); + constexpr float MIN32 = std::numeric_limits::min(); + constexpr float MAX32 = std::numeric_limits::max(); - constexpr float EPSILON64 = std::numeric_limits::epsilon(); - constexpr float MIN64 = std::numeric_limits::min(); - constexpr float MAX64 = std::numeric_limits::max(); - } // namespace fp + constexpr float EPSILON64 = std::numeric_limits::epsilon(); + constexpr float MIN64 = std::numeric_limits::min(); + constexpr float MAX64 = std::numeric_limits::max(); // Integer special values using numeric_limits - namespace int_limits { - constexpr int8_t I8_MIN = std::numeric_limits::min(); - constexpr int8_t I8_MAX = std::numeric_limits::max(); - constexpr uint8_t U8_MAX = std::numeric_limits::max(); - - constexpr int16_t I16_MIN = std::numeric_limits::min(); - constexpr int16_t I16_MAX = std::numeric_limits::max(); - constexpr uint16_t U16_MAX = std::numeric_limits::max(); - - constexpr int32_t I32_MIN = std::numeric_limits::min(); - constexpr int32_t I32_MAX = std::numeric_limits::max(); - constexpr uint32_t U32_MAX = std::numeric_limits::max(); - - constexpr int64_t I64_MIN = std::numeric_limits::min(); - constexpr int64_t I64_MAX = std::numeric_limits::max(); - constexpr uint64_t U64_MAX = std::numeric_limits::max(); - } // namespace int_limits + constexpr int8_t I8_MIN = std::numeric_limits::min(); + constexpr int8_t I8_MAX = std::numeric_limits::max(); + constexpr uint8_t U8_MAX = std::numeric_limits::max(); + + constexpr int16_t I16_MIN = std::numeric_limits::min(); + constexpr int16_t I16_MAX = std::numeric_limits::max(); + constexpr uint16_t U16_MAX = std::numeric_limits::max(); + + constexpr int32_t I32_MIN = std::numeric_limits::min(); + constexpr int32_t I32_MAX = std::numeric_limits::max(); + constexpr uint32_t U32_MAX = std::numeric_limits::max(); + + constexpr int64_t I64_MIN = std::numeric_limits::min(); + constexpr int64_t I64_MAX = std::numeric_limits::max(); + constexpr uint64_t U64_MAX = std::numeric_limits::max(); } // namespace gkit::math \ No newline at end of file diff --git a/test/math/test_math.cpp b/test/math/test_math.cpp index 0ff474f..f997a7a 100644 --- a/test/math/test_math.cpp +++ b/test/math/test_math.cpp @@ -14,17 +14,17 @@ int main() { assert(ScalarLimits::epsilon_v > 0); // fp constants tests - assert(fp::EPSILON32 > 0); - assert(fp::MIN32 > 0); - assert(fp::MAX32 > fp::MIN32); + assert(EPSILON32 > 0); + assert(MIN32 > 0); + assert(MAX32 > MIN32); // integer constants tests - assert(int_limits::I8_MIN == -128); - assert(int_limits::I8_MAX == 127); - assert(int_limits::U8_MAX == 255); - assert(int_limits::I16_MIN == -32768); - assert(int_limits::I16_MAX == 32767); - assert(int_limits::U16_MAX == 65535); + assert(I8_MIN == -128); + assert(I8_MAX == 127); + assert(U8_MAX == 255); + assert(I16_MIN == -32768); + assert(I16_MAX == 32767); + assert(U16_MAX == 65535); // ====== Test constants.hpp ====== diff --git a/test/math/test_vector2.cpp b/test/math/test_vector2.cpp index b37eda2..c9f5cd0 100644 --- a/test/math/test_vector2.cpp +++ b/test/math/test_vector2.cpp @@ -42,20 +42,20 @@ auto main() -> int { Vector2 vec_div = vec1 / 10.0f; std::cout << "vec1 / 10: " << vec_str(vec_div) << std::endl; - assert(std::abs(vec_div.x - 0.1f) < gkit::math::fp::EPSILON32 && std::abs(vec_div.y - 0.2f) < gkit::math::fp::EPSILON32); + assert(std::abs(vec_div.x - 0.1f) < gkit::math::EPSILON32 && std::abs(vec_div.y - 0.2f) < gkit::math::EPSILON32); // Length std::cout << "vec1.length(): " << vec1.length() << std::endl; - assert(std::abs(vec1.length() - std::sqrt(5.0f)) < gkit::math::fp::EPSILON32); + assert(std::abs(vec1.length() - std::sqrt(5.0f)) < gkit::math::EPSILON32); // Length squared std::cout << "vec1.length_sq(): " << vec1.length_sq() << std::endl; - assert(std::abs(vec1.length_sq() - 5.0f) < gkit::math::fp::EPSILON32); + assert(std::abs(vec1.length_sq() - 5.0f) < gkit::math::EPSILON32); // Normalization vec1 = Vector2::normalize(vec1); std::cout << "vec1 after normalize: " << vec_str(vec1) << std::endl; - assert(std::abs(vec1.length() - 1.0f) < gkit::math::fp::EPSILON32); + assert(std::abs(vec1.length() - 1.0f) < gkit::math::EPSILON32); // Reset for further tests Vector2 a(1.0f, 0.0f); @@ -78,13 +78,13 @@ auto main() -> int { Vector2 c(3.0f, 4.0f); Vector2 c_normalized = Vector2::normalize(c); std::cout << "Vector2::normalize(3,4): " << vec_str(c_normalized) << std::endl; - assert(std::abs(c_normalized.length() - 1.0f) < gkit::math::fp::EPSILON32); + assert(std::abs(c_normalized.length() - 1.0f) < gkit::math::EPSILON32); // Lerp Vector2 lerp_result = Vector2::lerp(a, b, 0.5f); std::cout << "Vector2::lerp((1,0), (0,1), 0.5): " << vec_str(lerp_result) << std::endl; - assert(std::abs(lerp_result.x - 0.5f) < gkit::math::fp::EPSILON32); - assert(std::abs(lerp_result.y - 0.5f) < gkit::math::fp::EPSILON32); + assert(std::abs(lerp_result.x - 0.5f) < gkit::math::EPSILON32); + assert(std::abs(lerp_result.y - 0.5f) < gkit::math::EPSILON32); // Min / Max Vector2 min_result = Vector2::min(a, b); @@ -105,15 +105,15 @@ auto main() -> int { Vector2 n(0.0f, 1.0f); // Reflect off horizontal surface Vector2 reflect_result = Vector2::reflect(v, n); std::cout << "Vector2::reflect((1,1), (0,1)): " << vec_str(reflect_result) << std::endl; - assert(std::abs(reflect_result.x - 1.0f) < gkit::math::fp::EPSILON32); - assert(std::abs(reflect_result.y - (-1.0f)) < gkit::math::fp::EPSILON32); + assert(std::abs(reflect_result.x - 1.0f) < gkit::math::EPSILON32); + assert(std::abs(reflect_result.y - (-1.0f)) < gkit::math::EPSILON32); // Distance Vector2 p1(0.0f, 0.0f); Vector2 p2(3.0f, 4.0f); float dist = Vector2::distance(p1, p2); std::cout << "Vector2::distance((0,0), (3,4)): " << dist << std::endl; - assert(std::abs(dist - 5.0f) < gkit::math::fp::EPSILON32); + assert(std::abs(dist - 5.0f) < gkit::math::EPSILON32); std::cout << "\nAll tests passed!" << std::endl; return 0;