6#include <initializer_list>
13#include "structure/math/spk_safe_comparand.hpp"
15#include "structure/math/spk_vector2.hpp"
32 template <
typename TType>
64 template <
typename TX,
typename TY,
typename TZ>
65 requires(std::is_constructible_v<TType, TX> && std::is_constructible_v<TType, TY> &&
66 std::is_constructible_v<TType, TZ>)
67 constexpr IVector3(
const TX &p_x,
const TY &p_y,
const TZ &p_z) :
68 x(
static_cast<TType
>(p_x)),
69 y(
static_cast<TType
>(p_y)),
70 z(
static_cast<TType
>(p_z))
81 template <
typename TOtherVector,
typename TZ>
82 requires(std::is_constructible_v<TType, TOtherVector> && std::is_constructible_v<TType, TZ>)
84 x(
static_cast<TType
>(p_other.
x)),
85 y(
static_cast<TType
>(p_other.
y)),
86 z(
static_cast<TType
>(p_z))
95 template <
typename TOther>
96 requires std::is_constructible_v<TType, TOther>
98 x(static_cast<TType>(p_other.
x)),
99 y(static_cast<TType>(p_other.
y)),
100 z(static_cast<TType>(p_other.
z))
108 template <
typename TOther>
109 requires std::is_constructible_v<TType, TOther>
110 explicit constexpr IVector3(
const TOther &p_value) :
111 x(static_cast<TType>(p_value)),
112 y(static_cast<TType>(p_value)),
113 z(static_cast<TType>(p_value))
132 std::ostringstream stream;
143 std::wostringstream stream;
156 p_stream <<
'(' << p_value.
x <<
", " << p_value.
y <<
", " << p_value.
z <<
')';
168 p_stream << L
'(' << p_value.
x << L
", " << p_value.
y << L
", " << p_value.
z << L
')';
192 return !(*
this == p_other);
237 throw std::invalid_argument(
"Can't divide by 0");
249 return IVector3(
x + p_scalar,
y + p_scalar,
z + p_scalar);
259 return IVector3(
x - p_scalar,
y - p_scalar,
z - p_scalar);
269 return IVector3(
x * p_scalar,
y * p_scalar,
z * p_scalar);
282 throw std::invalid_argument(
"Can't divide by 0");
284 return IVector3(
x / p_scalar,
y / p_scalar,
z / p_scalar);
296 return p_vector + p_scalar;
307 return IVector3(p_scalar - p_vector.
x, p_scalar - p_vector.
y, p_scalar - p_vector.
z);
319 return p_vector * p_scalar;
335 throw std::invalid_argument(
"Can't divide by 0");
337 return IVector3(p_scalar / p_vector.
x, p_scalar / p_vector.
y, p_scalar / p_vector.
z);
413 throw std::invalid_argument(
"Can't divide by 0");
474 throw std::invalid_argument(
"Can't divide by 0");
500 const auto px =
static_cast<float>(
x);
501 const auto py =
static_cast<float>(
y);
502 const auto pz =
static_cast<float>(
z);
503 return (px * px) + (py * py) + (pz * pz);
513 return static_cast<float>(std::sqrt(
static_cast<double>(
squaredLength())));
527 throw std::runtime_error(
"Can't normilize a vector of norm == 0");
529 return (this->
operator/(std::sqrt(baseSquareLenght)));
540 return (*
this - p_other).squaredLength();
551 return (*
this - p_other).length();
562 const auto px =
static_cast<float>(
x);
563 const auto py =
static_cast<float>(
y);
564 const auto pz =
static_cast<float>(
z);
565 return (px *
static_cast<float>(p_other.
x)) +
566 (py *
static_cast<float>(p_other.
y)) +
567 (pz *
static_cast<float>(p_other.
z));
578 const auto ax =
static_cast<float>(
x);
579 const auto ay =
static_cast<float>(
y);
580 const auto az =
static_cast<float>(
z);
581 const auto bx =
static_cast<float>(p_other.
x);
582 const auto by =
static_cast<float>(p_other.
y);
583 const auto bz =
static_cast<float>(p_other.
z);
586 static_cast<TType
>((ay * bz) - (az * by)),
587 static_cast<TType
>((az * bx) - (ax * bz)),
588 static_cast<TType
>((ax * by) - (ay * bx)));
624 template <
typename TAlpha>
625 requires std::is_arithmetic_v<TAlpha>
628 const auto alpha =
static_cast<float>(p_alpha);
629 const auto startX =
static_cast<float>(p_from.
x);
630 const auto startY =
static_cast<float>(p_from.
y);
631 const auto startZ =
static_cast<float>(p_from.
z);
632 const auto deltaX =
static_cast<float>(p_to.
x) - startX;
633 const auto deltaY =
static_cast<float>(p_to.
y) - startY;
634 const auto deltaZ =
static_cast<float>(p_to.
z) - startZ;
636 static_cast<TType
>(startX + (deltaX * alpha)),
637 static_cast<TType
>(startY + (deltaY * alpha)),
638 static_cast<TType
>(startZ + (deltaZ * alpha)));
651 std::min(p_a.
x, p_b.
x),
652 std::min(p_a.
y, p_b.
y),
653 std::min(p_a.
z, p_b.
z));
665 template <
typename... TOthers>
666 requires(
sizeof...(TOthers) > 0 && (std::is_same_v<TOthers, IVector3> && ...))
669 return min(
min(p_a, p_b), p_rest...);
680 if (p_values.size() == 0)
682 throw std::invalid_argument(
"IVector3::min requires at least one operand");
685 auto result = *p_values.begin();
686 for (
auto it = std::next(p_values.begin()); it != p_values.end(); ++it)
688 result =
min(result, *it);
703 std::max(p_a.
x, p_b.
x),
704 std::max(p_a.
y, p_b.
y),
705 std::max(p_a.
z, p_b.
z));
716 template <
typename... TOthers>
717 requires(
sizeof...(TOthers) > 0 && (std::is_same_v<TOthers, IVector3> && ...))
720 return max(
max(p_a, p_b), p_rest...);
731 if (p_values.size() == 0)
733 throw std::invalid_argument(
"IVector3::max requires at least one operand");
736 auto result = *p_values.begin();
737 for (
auto it = std::next(p_values.begin()); it != p_values.end(); ++it)
739 result =
max(result, *it);
755 std::min(p_boundA.
x, p_boundB.
x),
756 std::min(p_boundA.
y, p_boundB.
y),
757 std::min(p_boundA.
z, p_boundB.
z));
759 std::max(p_boundA.
x, p_boundB.
x),
760 std::max(p_boundA.
y, p_boundB.
y),
761 std::max(p_boundA.
z, p_boundB.
z));
764 std::clamp(p_value.
x, low.
x, high.
x),
765 std::clamp(p_value.
y, low.
y, high.
y),
766 std::clamp(p_value.
z, low.
z, high.
z));
778 return clamp(*
this, p_boundA, p_boundB);
792 std::min(p_boundA.
x, p_boundB.
x),
793 std::min(p_boundA.
y, p_boundB.
y),
794 std::min(p_boundA.
z, p_boundB.
z));
796 std::max(p_boundA.
x, p_boundB.
x),
797 std::max(p_boundA.
y, p_boundB.
y),
798 std::max(p_boundA.
z, p_boundB.
z));
800 return (p_value.
x >= low.
x && p_value.
x <= high.
x) &&
801 (p_value.
y >= low.
y && p_value.
y <= high.
y) &&
802 (p_value.
z >= low.
z && p_value.
z <= high.
z);
810 template <
typename TOther>
811 requires std::is_constructible_v<TOther, TType>
815 static_cast<TOther
>(
x),
816 static_cast<TOther
>(
y),
817 static_cast<TOther
>(
z));
821 template <
typename TType>
824 template <
typename TType>
826 static_cast<TType
>(1),
827 static_cast<TType
>(1),
828 static_cast<TType
>(1)};
2D value type holding two components with basic arithmetic helpers.
Definition spk_vector2.hpp:35
TType x
X component.
Definition spk_vector2.hpp:44
TType y
Y component.
Definition spk_vector2.hpp:48
3D value type with common arithmetic helpers.
Definition spk_vector3.hpp:34
IVector3 operator-() const
Unary minus.
Definition spk_vector3.hpp:353
IVector3 operator/(const TType &p_scalar) const
Divides each component by a scalar.
Definition spk_vector3.hpp:278
std::wstring toWstring() const
Converts the vector to a wide string.
Definition spk_vector3.hpp:141
constexpr IVector3(const TX &p_x, const TY &p_y, const TZ &p_z)
Builds a vector from three components.
Definition spk_vector3.hpp:67
IVector2< TType > yz() const
Projects this vector into 2D using y and z components.
Definition spk_vector3.hpp:604
float_t x
Definition spk_vector3.hpp:43
constexpr IVector3(const IVector3< TOther > &p_other)
Converting constructor from another component type.
Definition spk_vector3.hpp:97
constexpr IVector3(const TOther &p_value)
Fills all components with the same value.
Definition spk_vector3.hpp:110
float length() const
Computes Euclidean length.
Definition spk_vector3.hpp:511
friend std::wostream & operator<<(std::wostream &p_stream, const IVector3 &p_value)
Streams the vector to a wide output stream.
Definition spk_vector3.hpp:166
IVector3< float > normalize() const
Return the vector once normalized by its length.
Definition spk_vector3.hpp:521
float dot(const IVector3 &p_other) const
Computes dot product with another vector.
Definition spk_vector3.hpp:560
friend IVector3 operator*(const TType &p_scalar, const IVector3 &p_vector)
Multiplies a scalar by a vector (scalar on the left side).
Definition spk_vector3.hpp:317
static const IVector3 Zero
Definition spk_vector3.hpp:120
IVector3 & operator/=(const TType &p_scalar)
In-place scalar division.
Definition spk_vector3.hpp:470
bool operator==(const IVector3 &p_other) const
Checks component-wise equality using SafeComparand.
Definition spk_vector3.hpp:177
static IVector3 min(std::initializer_list< IVector3 > p_values)
Component-wise minimum across an initializer list.
Definition spk_vector3.hpp:678
std::string toString() const
Converts the vector to a string.
Definition spk_vector3.hpp:130
IVector3 & operator/=(const IVector3 &p_other)
In-place component-wise division.
Definition spk_vector3.hpp:407
IVector3 operator+(const IVector3 &p_other) const
Component-wise addition.
Definition spk_vector3.hpp:200
IVector3 & operator+=(const IVector3 &p_other)
In-place component-wise addition.
Definition spk_vector3.hpp:364
IVector3 operator-(const IVector3 &p_other) const
Component-wise subtraction.
Definition spk_vector3.hpp:210
friend IVector3 operator/(const TType &p_scalar, const IVector3 &p_vector)
Divides a scalar by each vector component (scalar on the left side).
Definition spk_vector3.hpp:329
static bool isBetween(const IVector3 &p_value, const IVector3 &p_boundA, const IVector3 &p_boundB)
Checks whether a vector lies within inclusive bounds.
Definition spk_vector3.hpp:789
IVector3 & operator*=(const TType &p_scalar)
In-place scalar multiplication.
Definition spk_vector3.hpp:455
IVector3 clamped(const IVector3 &p_boundA, const IVector3 &p_boundB) const
Returns a clamped copy of this vector.
Definition spk_vector3.hpp:776
static IVector3 max(const IVector3 &p_a, const IVector3 &p_b)
Component-wise maximum of two vectors.
Definition spk_vector3.hpp:700
float squaredDistance(const IVector3 &p_other) const
Computes squared distance to another vector.
Definition spk_vector3.hpp:538
float_t z
Definition spk_vector3.hpp:51
IVector2< TType > xy() const
Projects this vector into 2D using x and y components.
Definition spk_vector3.hpp:595
friend std::ostream & operator<<(std::ostream &p_stream, const IVector3 &p_value)
Streams the vector to an output stream.
Definition spk_vector3.hpp:154
bool isZero() const
Checks if all components are zero.
Definition spk_vector3.hpp:486
float_t y
Definition spk_vector3.hpp:47
IVector3 & operator*=(const IVector3 &p_other)
In-place component-wise multiplication.
Definition spk_vector3.hpp:392
static IVector3 clamp(const IVector3 &p_value, const IVector3 &p_boundA, const IVector3 &p_boundB)
Clamps each component of a vector between two bounds.
Definition spk_vector3.hpp:752
IVector3 & operator-=(const TType &p_scalar)
In-place scalar subtraction.
Definition spk_vector3.hpp:441
IVector3 & operator+=(const TType &p_scalar)
In-place scalar addition.
Definition spk_vector3.hpp:427
IVector3 operator-(const TType &p_scalar) const
Subtracts a scalar from each component.
Definition spk_vector3.hpp:257
static IVector3 min(const IVector3 &p_a, const IVector3 &p_b)
Component-wise minimum of two vectors.
Definition spk_vector3.hpp:648
IVector3 inverse() const
Return the inverse vector.
Definition spk_vector3.hpp:344
constexpr IVector3(const IVector2< TOtherVector > &p_other, const TZ &p_z)
Builds a vector from a 2D vector and Z component.
Definition spk_vector3.hpp:83
constexpr IVector3()=default
Builds a zero vector.
IVector3 operator*(const TType &p_scalar) const
Multiplies each component by a scalar.
Definition spk_vector3.hpp:267
float distance(const IVector3 &p_other) const
Computes Euclidean distance to another vector.
Definition spk_vector3.hpp:549
IVector3 operator*(const IVector3 &p_other) const
Component-wise multiplication.
Definition spk_vector3.hpp:220
TType value_type
Component type stored by the vector.
Definition spk_vector3.hpp:38
bool operator!=(const IVector3 &p_other) const
Negation of equality.
Definition spk_vector3.hpp:190
IVector3 cross(const IVector3 &p_other) const
Computes 3D cross product.
Definition spk_vector3.hpp:576
float squaredLength() const
Computes squared vector length.
Definition spk_vector3.hpp:498
IVector3 operator/(const IVector3 &p_other) const
Component-wise division.
Definition spk_vector3.hpp:231
static IVector3 lerp(const IVector3 &p_from, const IVector3 &p_to, const TAlpha &p_alpha)
Linearly interpolates between two vectors.
Definition spk_vector3.hpp:626
static const IVector3 One
Definition spk_vector3.hpp:124
IVector3 operator+(const TType &p_scalar) const
Adds a scalar to each component.
Definition spk_vector3.hpp:247
static IVector3 max(std::initializer_list< IVector3 > p_values)
Component-wise maximum across an initializer list.
Definition spk_vector3.hpp:729
friend IVector3 operator-(const TType &p_scalar, const IVector3 &p_vector)
Subtracts vector components from a scalar (scalar on the left side).
Definition spk_vector3.hpp:305
friend IVector3 operator+(const TType &p_scalar, const IVector3 &p_vector)
Adds a scalar to a vector (scalar on the left side).
Definition spk_vector3.hpp:294
IVector3 & operator-=(const IVector3 &p_other)
In-place component-wise subtraction.
Definition spk_vector3.hpp:378
Wraps arithmetic values to compare with tolerance for floating-point inputs.
Definition spk_safe_comparand.hpp:17