mirror of
https://github.com/orange-cpp/omath.git
synced 2026-06-12 02:04:35 +00:00
added more gcem to angle vec2,3
This commit is contained in:
+1
-1
@@ -239,7 +239,7 @@
|
||||
"hidden": true,
|
||||
"inherits": ["darwin-base", "vcpkg-base"],
|
||||
"cacheVariables": {
|
||||
"VCPKG_MANIFEST_FEATURES": "tests;imgui;avx2;examples;lua"
|
||||
"VCPKG_MANIFEST_FEATURES": "tests;imgui;avx2;examples;lua;gcem"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "omath/internal/optional_constexpr_math.hpp"
|
||||
#include <cmath>
|
||||
#include <format>
|
||||
#include <tuple>
|
||||
@@ -116,9 +117,13 @@ namespace omath
|
||||
|
||||
// Basic vector operations
|
||||
[[nodiscard("You must use distance")]]
|
||||
Type distance_to(const Vector2& other) const noexcept
|
||||
OMATH_CONSTEXPR Type distance_to(const Vector2& other) const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(distance_to_sqr(other));
|
||||
#else
|
||||
return std::sqrt(distance_to_sqr(other));
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use squared distance")]]
|
||||
@@ -136,7 +141,11 @@ namespace omath
|
||||
#ifndef _MSC_VER
|
||||
[[nodiscard("You must use length")]] constexpr Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::hypot(this->x, this->y);
|
||||
#else
|
||||
return std::hypot(this->x, this->y);
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]] constexpr Vector2 normalized() const noexcept
|
||||
@@ -146,13 +155,17 @@ namespace omath
|
||||
}
|
||||
#else
|
||||
[[nodiscard("You must use length")]]
|
||||
Type length() const noexcept
|
||||
OMATH_CONSTEXPR Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::hypot(x, y);
|
||||
#else
|
||||
return std::hypot(x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]]
|
||||
Vector2 normalized() const noexcept
|
||||
OMATH_CONSTEXPR Vector2 normalized() const noexcept
|
||||
{
|
||||
const Type len = length();
|
||||
return len > static_cast<Type>(0) ? *this / len : *this;
|
||||
@@ -216,24 +229,24 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator<(const Vector2& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator<(const Vector2& other) const noexcept
|
||||
{
|
||||
return length() < other.length();
|
||||
}
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator>(const Vector2& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator>(const Vector2& other) const noexcept
|
||||
{
|
||||
return length() > other.length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator<=(const Vector2& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator<=(const Vector2& other) const noexcept
|
||||
{
|
||||
return length() <= other.length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator>=(const Vector2& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator>=(const Vector2& other) const noexcept
|
||||
{
|
||||
return length() >= other.length();
|
||||
}
|
||||
|
||||
@@ -140,20 +140,24 @@ namespace omath
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
[[nodiscard("You must use length")]] constexpr Type length() const
|
||||
[[nodiscard("You must use length")]] constexpr Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(this->x * this->x + this->y * this->y + z * z);
|
||||
#else
|
||||
return std::hypot(this->x, this->y, z);
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use 2D length")]] constexpr Type length_2d() const
|
||||
[[nodiscard("You must use 2D length")]] constexpr Type length_2d() const noexcept
|
||||
{
|
||||
return Vector2<Type>::length();
|
||||
}
|
||||
[[nodiscard("You must use distance")]] Type distance_to(const Vector3& other) const
|
||||
[[nodiscard("You must use distance")]] OMATH_CONSTEXPR Type distance_to(const Vector3& other) const noexcept
|
||||
{
|
||||
return (*this - other).length();
|
||||
}
|
||||
[[nodiscard("You must use normalized vector")]] constexpr Vector3 normalized() const
|
||||
[[nodiscard("You must use normalized vector")]] constexpr Vector3 normalized() const noexcept
|
||||
{
|
||||
const Type length_value = this->length();
|
||||
|
||||
@@ -161,13 +165,17 @@ namespace omath
|
||||
}
|
||||
#else
|
||||
[[nodiscard("You must use length")]]
|
||||
Type length() const noexcept
|
||||
OMATH_CONSTEXPR Type length() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
|
||||
#else
|
||||
return std::hypot(this->x, this->y, z);
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use normalized vector")]]
|
||||
Vector3 normalized() const noexcept
|
||||
OMATH_CONSTEXPR Vector3 normalized() const noexcept
|
||||
{
|
||||
const Type len = this->length();
|
||||
|
||||
@@ -175,13 +183,13 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard("You must use 2D length")]]
|
||||
Type length_2d() const noexcept
|
||||
OMATH_CONSTEXPR Type length_2d() const noexcept
|
||||
{
|
||||
return Vector2<Type>::length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use distance")]]
|
||||
Type distance_to(const Vector3& v_other) const noexcept
|
||||
OMATH_CONSTEXPR Type distance_to(const Vector3& v_other) const noexcept
|
||||
{
|
||||
return (*this - v_other).length();
|
||||
}
|
||||
@@ -249,24 +257,28 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard("You must use direction check result")]]
|
||||
bool point_to_same_direction(const Vector3& other) const
|
||||
OMATH_CONSTEXPR bool point_to_same_direction(const Vector3& other) const
|
||||
{
|
||||
return dot(other) > static_cast<Type>(0);
|
||||
}
|
||||
[[nodiscard("You must use angle between vectors")]]
|
||||
std::expected<Angle<float, 0.f, 180.f, AngleFlags::Clamped>, Vector3Error>
|
||||
OMATH_CONSTEXPR std::expected<Angle<float, 0.f, 180.f, AngleFlags::Clamped>, Vector3Error>
|
||||
angle_between(const Vector3& other) const noexcept
|
||||
{
|
||||
const auto bottom = length() * other.length();
|
||||
|
||||
if (bottom == static_cast<Type>(0))
|
||||
return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE);
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(gcem::acos(dot(other) / bottom));
|
||||
#else
|
||||
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard("You must use perpendicularity check result")]]
|
||||
bool is_perpendicular(const Vector3& other, Type epsilon = static_cast<Type>(0.0001)) const noexcept
|
||||
OMATH_CONSTEXPR bool is_perpendicular(const Vector3& other,
|
||||
Type epsilon = static_cast<Type>(0.0001)) const noexcept
|
||||
{
|
||||
if (const auto angle = angle_between(other))
|
||||
return std::abs(angle->as_degrees() - static_cast<Type>(90)) <= epsilon;
|
||||
@@ -287,25 +299,25 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator<(const Vector3& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator<(const Vector3& other) const noexcept
|
||||
{
|
||||
return length() < other.length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator>(const Vector3& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator>(const Vector3& other) const noexcept
|
||||
{
|
||||
return length() > other.length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator<=(const Vector3& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator<=(const Vector3& other) const noexcept
|
||||
{
|
||||
return length() <= other.length();
|
||||
}
|
||||
|
||||
[[nodiscard("You must use comparison result")]]
|
||||
bool operator>=(const Vector3& other) const noexcept
|
||||
OMATH_CONSTEXPR bool operator>=(const Vector3& other) const noexcept
|
||||
{
|
||||
return length() >= other.length();
|
||||
}
|
||||
@@ -321,7 +333,7 @@ namespace omath
|
||||
template<> struct std::hash<omath::Vector3<float>>
|
||||
{
|
||||
[[nodiscard("You must use hash value")]]
|
||||
std::size_t operator()(const omath::Vector3<float>& vec) const noexcept
|
||||
constexpr std::size_t operator()(const omath::Vector3<float>& vec) const noexcept
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
constexpr std::hash<float> hasher;
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "omath/internal/optional_constexpr_math.hpp"
|
||||
#include "omath/trigonometry/angles.hpp"
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
#include <utility>
|
||||
#include "omath/internal/optional_constexpr_math.hpp"
|
||||
|
||||
namespace omath
|
||||
{
|
||||
@@ -104,13 +104,18 @@ namespace omath
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type atan() const noexcept
|
||||
OMATH_CONSTEXPR Type atan() const noexcept
|
||||
{
|
||||
#ifdef OMATH_USE_GCEM
|
||||
return gcem::atan(as_radians());
|
||||
#else
|
||||
return std::atan(as_radians());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Type cot() const noexcept
|
||||
OMATH_CONSTEXPR Type cot() const noexcept
|
||||
{
|
||||
return cos() / sin();
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// Created by Vlad on 02.09.2024.
|
||||
//
|
||||
|
||||
#include <omath/linear_algebra/vector2.hpp>
|
||||
#include <cfloat> // For FLT_MAX and FLT_MIN
|
||||
#include <cmath> // For std::isinf and std::isnan
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/linear_algebra/vector2.hpp>
|
||||
|
||||
using namespace omath;
|
||||
|
||||
@@ -399,7 +399,6 @@ TEST_F(UnitTestVector2, GreaterEqualOperator)
|
||||
EXPECT_TRUE(omath::Vector2(1.f, 1.f) >= omath::Vector2<float>{});
|
||||
}
|
||||
|
||||
|
||||
// ── Cast operator tests ──────────────────────────────────────────────────────
|
||||
|
||||
TEST(Vector2Cast, FloatToDouble)
|
||||
@@ -463,3 +462,9 @@ static_assert(Vector2(1.0f, 2.0f).length_sqr() == 5.0f, "LengthSqr should be 5")
|
||||
static_assert(Vector2(1.0f, 2.0f).dot(Vector2(4.0f, 5.0f)) == 14.0f, "Dot product should be 14");
|
||||
static_assert(Vector2(4.0f, 5.0f).distance_to_sqr(Vector2(1.0f, 2.0f)) == 18.0f, "DistToSqr should be 18");
|
||||
static_assert(Vector2(-1.0f, -2.0f).abs() == Vector2(1.0f, 2.0f), "Abs should convert negative values to positive");
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
static_assert(Vector2(3.0f, 4.0f).length() == 5.0f, "Length should be constexpr with gcem");
|
||||
static_assert(Vector2(0.0f, 0.0f).distance_to(Vector2(3.0f, 4.0f)) == 5.0f, "Distance should be constexpr with gcem");
|
||||
static_assert(Vector2(1.0f, 1.0f) < Vector2(3.0f, 4.0f), "Comparison should be constexpr with gcem");
|
||||
#endif
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// Created by Vlad on 01.09.2024.
|
||||
//
|
||||
|
||||
#include <omath/linear_algebra/vector3.hpp>
|
||||
#include <cfloat> // For FLT_MAX, FLT_MIN
|
||||
#include <cmath>
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits> // For std::numeric_limits
|
||||
#include <omath/linear_algebra/vector3.hpp>
|
||||
|
||||
using namespace omath;
|
||||
|
||||
@@ -44,9 +44,7 @@ TEST(Vector3More, ArithmeticAndDotCross)
|
||||
|
||||
EXPECT_FLOAT_EQ(a.dot(b), 0.f);
|
||||
// manual cross product check
|
||||
const auto cr = Vector3<float>{ a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x };
|
||||
const auto cr = Vector3<float>{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
|
||||
constexpr Vector3<float> expect_cr{0.f, 0.f, 1.f};
|
||||
EXPECT_EQ(cr, expect_cr);
|
||||
}
|
||||
@@ -481,10 +479,8 @@ TEST_F(UnitTestVector3, AsTuple)
|
||||
// Test AsTuple method
|
||||
TEST_F(UnitTestVector3, AngleBeatween)
|
||||
{
|
||||
EXPECT_NEAR(Vector3(0.0f, 0.0f, 1.0f).angle_between({1, 0, 0}).value().as_degrees(),
|
||||
90.0f, 0.001f);
|
||||
EXPECT_NEAR(Vector3(0.0f, 0.0f, 1.0f).angle_between({0.0f, 0.0f, 1.0f}).value().as_degrees(),
|
||||
0.0f, 0.001f);
|
||||
EXPECT_NEAR(Vector3(0.0f, 0.0f, 1.0f).angle_between({1, 0, 0}).value().as_degrees(), 90.0f, 0.001f);
|
||||
EXPECT_NEAR(Vector3(0.0f, 0.0f, 1.0f).angle_between({0.0f, 0.0f, 1.0f}).value().as_degrees(), 0.0f, 0.001f);
|
||||
EXPECT_FALSE(Vector3(0.0f, 0.0f, 0.0f).angle_between({0.0f, 0.0f, 1.0f}).has_value());
|
||||
}
|
||||
|
||||
@@ -585,4 +581,19 @@ TEST(Vector3Cast, SameTypeRoundtrip)
|
||||
static_assert(Vector3(1.0f, 2.0f, 3.0f).length_sqr() == 14.0f, "LengthSqr should be 14");
|
||||
static_assert(Vector3(1.0f, 2.0f, 3.0f).dot(Vector3(4.0f, 5.0f, 6.0f)) == 32.0f, "Dot product should be 32");
|
||||
static_assert(Vector3(4.0f, 5.0f, 6.0f).distance_to_sqr(Vector3(1.0f, 2.0f, 3.0f)) == 27.0f, "DistToSqr should be 27");
|
||||
static_assert(Vector3(-1.0f, -2.0f, -3.0f).abs() == Vector3(1.0f, 2.0f, 3.0f), "Abs should convert negative values to positive");
|
||||
static_assert(Vector3(-1.0f, -2.0f, -3.0f).abs() == Vector3(1.0f, 2.0f, 3.0f),
|
||||
"Abs should convert negative values to positive");
|
||||
|
||||
#ifdef OMATH_USE_GCEM
|
||||
static_assert(Vector3(1.0f, 2.0f, 2.0f).length() == 3.0f, "Length should be constexpr with gcem");
|
||||
static_assert(Vector3(0.0f, 0.0f, 0.0f).distance_to(Vector3(1.0f, 2.0f, 2.0f)) == 3.0f,
|
||||
"Distance should be constexpr with gcem");
|
||||
static_assert(Vector3(1.0f, 1.0f, 1.0f) < Vector3(3.0f, 4.0f, 5.0f), "Comparison should be constexpr with gcem");
|
||||
static_assert(
|
||||
[]
|
||||
{
|
||||
constexpr auto angle = Vector3(1.0f, 0.0f, 0.0f).angle_between(Vector3(0.0f, 1.0f, 0.0f));
|
||||
return angle.has_value() && angle->as_degrees() > 89.999f && angle->as_degrees() < 90.001f;
|
||||
}(),
|
||||
"Angle between should be constexpr with gcem");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user