6#include <initializer_list>
13#include "structure/math/spk_safe_comparand.hpp"
15#include "structure/math/spk_vector3.hpp"
32 template <
typename TType>
69 template <
typename TX,
typename TY,
typename TZ,
typename TW>
70 requires(std::is_constructible_v<TType, TX> && std::is_constructible_v<TType, TY> &&
71 std::is_constructible_v<TType, TZ> && std::is_constructible_v<TType, TW>)
72 constexpr IVector4(
const TX &p_x,
const TY &p_y,
const TZ &p_z,
const TW &p_w) :
73 x(
static_cast<TType
>(p_x)),
74 y(
static_cast<TType
>(p_y)),
75 z(
static_cast<TType
>(p_z)),
76 w(
static_cast<TType
>(p_w))
89 template <
typename TOtherVector,
typename TZ,
typename TW>
90 requires(std::is_constructible_v<TType, TOtherVector> &&
91 std::is_constructible_v<TType, TZ> && std::is_constructible_v<TType, TW>)
93 x(
static_cast<TType
>(p_other.
x)),
94 y(
static_cast<TType
>(p_other.
y)),
95 z(
static_cast<TType
>(p_z)),
96 w(
static_cast<TType
>(p_w))
107 template <
typename TOtherVector,
typename TW>
108 requires(std::is_constructible_v<TType, TOtherVector> && std::is_constructible_v<TType, TW>)
110 x(
static_cast<TType
>(p_other.
x)),
111 y(
static_cast<TType
>(p_other.
y)),
112 z(
static_cast<TType
>(p_other.
z)),
113 w(
static_cast<TType
>(p_w))
122 template <
typename TOther>
123 requires std::is_constructible_v<TType, TOther>
125 x(static_cast<TType>(p_other.
x)),
126 y(static_cast<TType>(p_other.
y)),
127 z(static_cast<TType>(p_other.
z)),
128 w(static_cast<TType>(p_other.
w))
136 template <
typename TOther>
137 requires std::is_constructible_v<TType, TOther>
138 explicit constexpr IVector4(
const TOther &p_value) :
139 x(static_cast<TType>(p_value)),
140 y(static_cast<TType>(p_value)),
141 z(static_cast<TType>(p_value)),
142 w(static_cast<TType>(p_value))
161 std::ostringstream stream;
172 std::wostringstream stream;
185 p_stream <<
'(' << p_value.
x <<
", " << p_value.
y <<
", " << p_value.
z <<
", " << p_value.
w <<
')';
197 p_stream << L
'(' << p_value.
x << L
", " << p_value.
y << L
", " << p_value.
z << L
", " << p_value.
w << L
')';
222 return !(*
this == p_other);
232 return IVector4(
x + p_other.
x,
y + p_other.
y,
z + p_other.
z,
w + p_other.
w);
242 return IVector4(
x - p_other.
x,
y - p_other.
y,
z - p_other.
z,
w - p_other.
w);
252 return IVector4(
x * p_other.
x,
y * p_other.
y,
z * p_other.
z,
w * p_other.
w);
268 throw std::invalid_argument(
"Can't divide by 0");
270 return IVector4(
x / p_other.
x,
y / p_other.
y,
z / p_other.
z,
w / p_other.
w);
280 return IVector4(
x + p_scalar,
y + p_scalar,
z + p_scalar,
w + p_scalar);
290 return IVector4(
x - p_scalar,
y - p_scalar,
z - p_scalar,
w - p_scalar);
300 return IVector4(
x * p_scalar,
y * p_scalar,
z * p_scalar,
w * p_scalar);
313 throw std::invalid_argument(
"Can't divide by 0");
315 return IVector4(
x / p_scalar,
y / p_scalar,
z / p_scalar,
w / p_scalar);
327 return p_vector + p_scalar;
338 return IVector4(p_scalar - p_vector.
x, p_scalar - p_vector.
y, p_scalar - p_vector.
z, p_scalar - p_vector.
w);
350 return p_vector * p_scalar;
367 throw std::invalid_argument(
"Can't divide by 0");
369 return IVector4(p_scalar / p_vector.
x, p_scalar / p_vector.
y, p_scalar / p_vector.
z, p_scalar / p_vector.
w);
449 throw std::invalid_argument(
"Can't divide by 0");
514 throw std::invalid_argument(
"Can't divide by 0");
542 const auto px =
static_cast<float>(
x);
543 const auto py =
static_cast<float>(
y);
544 const auto pz =
static_cast<float>(
z);
545 const auto pw =
static_cast<float>(
w);
546 return (px * px) + (py * py) + (pz * pz) + (pw * pw);
560 throw std::runtime_error(
"Can't normilize a vector of norm == 0");
562 return (this->
operator/(std::sqrt(baseSquareLenght)));
572 return static_cast<float>(std::sqrt(
static_cast<double>(
squaredLength())));
583 return (*
this - p_other).squaredLength();
594 return (*
this - p_other).length();
604 const auto px =
static_cast<float>(
x);
605 const auto py =
static_cast<float>(
y);
606 const auto pz =
static_cast<float>(
z);
607 const auto pw =
static_cast<float>(
w);
608 return (px *
static_cast<float>(p_other.
x)) +
609 (py *
static_cast<float>(p_other.
y)) +
610 (pz *
static_cast<float>(p_other.
z)) +
611 (pw *
static_cast<float>(p_other.
w));
637 template <
typename TAlpha>
638 requires std::is_arithmetic_v<TAlpha>
641 const auto alpha =
static_cast<float>(p_alpha);
642 const auto startX =
static_cast<float>(p_from.
x);
643 const auto startY =
static_cast<float>(p_from.
y);
644 const auto startZ =
static_cast<float>(p_from.
z);
645 const auto startW =
static_cast<float>(p_from.
w);
646 const auto deltaX =
static_cast<float>(p_to.
x) - startX;
647 const auto deltaY =
static_cast<float>(p_to.
y) - startY;
648 const auto deltaZ =
static_cast<float>(p_to.
z) - startZ;
649 const auto deltaW =
static_cast<float>(p_to.
w) - startW;
651 static_cast<TType
>(startX + (deltaX * alpha)),
652 static_cast<TType
>(startY + (deltaY * alpha)),
653 static_cast<TType
>(startZ + (deltaZ * alpha)),
654 static_cast<TType
>(startW + (deltaW * alpha)));
667 std::min(p_a.
x, p_b.
x),
668 std::min(p_a.
y, p_b.
y),
669 std::min(p_a.
z, p_b.
z),
670 std::min(p_a.
w, p_b.
w));
682 template <
typename... TOthers>
683 requires(
sizeof...(TOthers) > 0 && (std::is_same_v<TOthers, IVector4> && ...))
686 return min(
min(p_a, p_b), p_rest...);
697 if (p_values.size() == 0)
699 throw std::invalid_argument(
"IVector4::min requires at least one operand");
702 auto result = *p_values.begin();
703 for (
auto it = std::next(p_values.begin()); it != p_values.end(); ++it)
705 result =
min(result, *it);
720 std::max(p_a.
x, p_b.
x),
721 std::max(p_a.
y, p_b.
y),
722 std::max(p_a.
z, p_b.
z),
723 std::max(p_a.
w, p_b.
w));
734 template <
typename... TOthers>
735 requires(
sizeof...(TOthers) > 0 && (std::is_same_v<TOthers, IVector4> && ...))
738 return max(
max(p_a, p_b), p_rest...);
749 if (p_values.size() == 0)
751 throw std::invalid_argument(
"IVector4::max requires at least one operand");
754 auto result = *p_values.begin();
755 for (
auto it = std::next(p_values.begin()); it != p_values.end(); ++it)
757 result =
max(result, *it);
773 std::min(p_boundA.
x, p_boundB.
x),
774 std::min(p_boundA.
y, p_boundB.
y),
775 std::min(p_boundA.
z, p_boundB.
z),
776 std::min(p_boundA.
w, p_boundB.
w));
778 std::max(p_boundA.
x, p_boundB.
x),
779 std::max(p_boundA.
y, p_boundB.
y),
780 std::max(p_boundA.
z, p_boundB.
z),
781 std::max(p_boundA.
w, p_boundB.
w));
784 std::clamp(p_value.
x, low.
x, high.
x),
785 std::clamp(p_value.
y, low.
y, high.
y),
786 std::clamp(p_value.
z, low.
z, high.
z),
787 std::clamp(p_value.
w, low.
w, high.
w));
799 return clamp(*
this, p_boundA, p_boundB);
813 std::min(p_boundA.
x, p_boundB.
x),
814 std::min(p_boundA.
y, p_boundB.
y),
815 std::min(p_boundA.
z, p_boundB.
z),
816 std::min(p_boundA.
w, p_boundB.
w));
818 std::max(p_boundA.
x, p_boundB.
x),
819 std::max(p_boundA.
y, p_boundB.
y),
820 std::max(p_boundA.
z, p_boundB.
z),
821 std::max(p_boundA.
w, p_boundB.
w));
823 return (p_value.
x >= low.
x && p_value.
x <= high.
x) &&
824 (p_value.
y >= low.
y && p_value.
y <= high.
y) &&
825 (p_value.
z >= low.
z && p_value.
z <= high.
z) &&
826 (p_value.
w >= low.
w && p_value.
w <= high.
w);
834 template <
typename TOther>
835 requires std::is_constructible_v<TOther, TType>
839 static_cast<TOther
>(
x),
840 static_cast<TOther
>(
y),
841 static_cast<TOther
>(
z),
842 static_cast<TOther
>(
w));
846 template <
typename TType>
849 template <
typename TType>
851 static_cast<TType
>(1),
852 static_cast<TType
>(1),
853 static_cast<TType
>(1),
854 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
TType x
X component.
Definition spk_vector3.hpp:43
TType z
Z component.
Definition spk_vector3.hpp:51
TType y
Y component.
Definition spk_vector3.hpp:47
4D value type with arithmetic helpers and swizzles.
Definition spk_vector4.hpp:34
float_t z
Definition spk_vector4.hpp:51
static bool isBetween(const IVector4 &p_value, const IVector4 &p_boundA, const IVector4 &p_boundB)
Checks whether a vector lies within inclusive bounds.
Definition spk_vector4.hpp:810
IVector4 operator-(const TType &p_scalar) const
Subtracts a scalar from each component.
Definition spk_vector4.hpp:288
IVector4 & operator*=(const IVector4 &p_other)
In-place component-wise multiplication.
Definition spk_vector4.hpp:426
constexpr IVector4(const IVector3< TOtherVector > &p_other, const TW &p_w)
Builds a vector from a 3D vector and W component.
Definition spk_vector4.hpp:109
float distance(const IVector4 &p_other) const
Computes Euclidean distance to another vector.
Definition spk_vector4.hpp:592
std::wstring toWstring() const
Converts the vector to a wide string.
Definition spk_vector4.hpp:170
IVector3< TType > xyz() const
Projects this vector into 3D using x, y, z components.
Definition spk_vector4.hpp:618
float_t w
Definition spk_vector4.hpp:55
constexpr IVector4(const IVector4< TOther > &p_other)
Converting constructor from another component type.
Definition spk_vector4.hpp:124
IVector4 operator-(const IVector4 &p_other) const
Component-wise subtraction.
Definition spk_vector4.hpp:240
float squaredDistance(const IVector4 &p_other) const
Computes squared distance to another vector.
Definition spk_vector4.hpp:581
std::string toString() const
Converts the vector to a string.
Definition spk_vector4.hpp:159
IVector4 & operator+=(const TType &p_scalar)
In-place scalar addition.
Definition spk_vector4.hpp:464
IVector4 & operator+=(const IVector4 &p_other)
In-place component-wise addition.
Definition spk_vector4.hpp:396
IVector4 & operator-=(const TType &p_scalar)
In-place scalar subtraction.
Definition spk_vector4.hpp:479
IVector4 & operator/=(const IVector4 &p_other)
In-place component-wise division.
Definition spk_vector4.hpp:442
IVector4 operator*(const TType &p_scalar) const
Multiplies each component by a scalar.
Definition spk_vector4.hpp:298
IVector4 & operator*=(const TType &p_scalar)
In-place scalar multiplication.
Definition spk_vector4.hpp:494
constexpr IVector4(const IVector2< TOtherVector > &p_other, const TZ &p_z, const TW &p_w)
Builds a vector from a 2D vector plus Z and W components.
Definition spk_vector4.hpp:92
float dot(const IVector4 &p_other) const
Computes dot product with another vector.
Definition spk_vector4.hpp:602
float length() const
Computes Euclidean length.
Definition spk_vector4.hpp:570
constexpr IVector4()=default
Builds a zero vector.
IVector4 inverse() const
Return the inverse vector.
Definition spk_vector4.hpp:376
static IVector4 max(const IVector4 &p_a, const IVector4 &p_b)
Component-wise maximum of two vectors.
Definition spk_vector4.hpp:717
static IVector4 min(const IVector4 &p_a, const IVector4 &p_b)
Component-wise minimum of two vectors.
Definition spk_vector4.hpp:664
IVector3< float > normalize() const
Return the vector once normalized by its length.
Definition spk_vector4.hpp:554
IVector4 & operator-=(const IVector4 &p_other)
In-place component-wise subtraction.
Definition spk_vector4.hpp:411
float squaredLength() const
Computes squared vector length.
Definition spk_vector4.hpp:540
static IVector4 min(std::initializer_list< IVector4 > p_values)
Component-wise minimum across an initializer list.
Definition spk_vector4.hpp:695
friend IVector4 operator-(const TType &p_scalar, const IVector4 &p_vector)
Subtracts vector components from a scalar (scalar on the left side).
Definition spk_vector4.hpp:336
static IVector4 max(std::initializer_list< IVector4 > p_values)
Component-wise maximum across an initializer list.
Definition spk_vector4.hpp:747
static IVector4 clamp(const IVector4 &p_value, const IVector4 &p_boundA, const IVector4 &p_boundB)
Clamps each component of a vector between two bounds.
Definition spk_vector4.hpp:770
static IVector4 lerp(const IVector4 &p_from, const IVector4 &p_to, const TAlpha &p_alpha)
Linearly interpolates between two vectors.
Definition spk_vector4.hpp:639
IVector4 operator+(const IVector4 &p_other) const
Component-wise addition.
Definition spk_vector4.hpp:230
IVector4 operator-() const
Unary minus.
Definition spk_vector4.hpp:385
float_t y
Definition spk_vector4.hpp:47
IVector4 operator*(const IVector4 &p_other) const
Component-wise multiplication.
Definition spk_vector4.hpp:250
friend IVector4 operator*(const TType &p_scalar, const IVector4 &p_vector)
Multiplies a scalar by a vector (scalar on the left side).
Definition spk_vector4.hpp:348
IVector4 clamped(const IVector4 &p_boundA, const IVector4 &p_boundB) const
Returns a clamped copy of this vector.
Definition spk_vector4.hpp:797
friend IVector4 operator+(const TType &p_scalar, const IVector4 &p_vector)
Adds a scalar to a vector (scalar on the left side).
Definition spk_vector4.hpp:325
TType value_type
Component type stored by the vector.
Definition spk_vector4.hpp:38
static const IVector4 Zero
Definition spk_vector4.hpp:149
IVector4 operator/(const TType &p_scalar) const
Divides each component by a scalar.
Definition spk_vector4.hpp:309
bool operator!=(const IVector4 &p_other) const
Negation of equality.
Definition spk_vector4.hpp:220
IVector4 operator/(const IVector4 &p_other) const
Component-wise division.
Definition spk_vector4.hpp:261
bool operator==(const IVector4 &p_other) const
Checks component-wise equality using SafeComparand.
Definition spk_vector4.hpp:206
constexpr IVector4(const TX &p_x, const TY &p_y, const TZ &p_z, const TW &p_w)
Builds a vector from four components.
Definition spk_vector4.hpp:72
friend std::ostream & operator<<(std::ostream &p_stream, const IVector4 &p_value)
Streams the vector to an output stream.
Definition spk_vector4.hpp:183
static const IVector4 One
Definition spk_vector4.hpp:153
friend IVector4 operator/(const TType &p_scalar, const IVector4 &p_vector)
Divides a scalar by each vector component (scalar on the left side).
Definition spk_vector4.hpp:360
bool isZero() const
Checks if all components are zero.
Definition spk_vector4.hpp:527
IVector4 operator+(const TType &p_scalar) const
Adds a scalar to each component.
Definition spk_vector4.hpp:278
constexpr IVector4(const TOther &p_value)
Fills all components with the same value.
Definition spk_vector4.hpp:138
IVector4 & operator/=(const TType &p_scalar)
In-place scalar division.
Definition spk_vector4.hpp:510
friend std::wostream & operator<<(std::wostream &p_stream, const IVector4 &p_value)
Streams the vector to a wide output stream.
Definition spk_vector4.hpp:195
float_t x
Definition spk_vector4.hpp:43
Wraps arithmetic values to compare with tolerance for floating-point inputs.
Definition spk_safe_comparand.hpp:17