33template<
typename T,
int N>
34requires (N > 0) && std::is_floating_point_v<T>
37 std::array<T, N> m_data{};
48 vec.m_data.fill(value);
69 constexpr Vector() noexcept = default;
79 template<std::convertible_to<T>... Args>
80 requires(sizeof...(Args) == N)
81 constexpr explicit
Vector(Args&&... args) noexcept {
82 m_data = {
static_cast<T
>(args)...};
88 constexpr T&
x() noexcept requires(N > 0) {
return m_data[0]; }
90 constexpr T&
y() noexcept requires(N > 1) {
return m_data[1]; }
92 constexpr T&
z() noexcept requires(N > 2) {
return m_data[2]; }
94 constexpr T&
w() noexcept requires(N > 3) {
return m_data[3]; }
97 constexpr const T&
x() const noexcept requires(N > 0) {
return m_data[0]; }
99 constexpr const T&
y() const noexcept requires(N > 1) {
return m_data[1]; }
101 constexpr const T&
z() const noexcept requires(N > 2) {
return m_data[2]; }
103 constexpr const T&
w() const noexcept requires(N > 3) {
return m_data[3]; }
106 constexpr int dims() const noexcept {
return N; }
118 if (index < 0 || index >= N) {
119 if (std::is_constant_evaluated()) {
120 throw "Compile-time error: Index out of range";
122 throw std::out_of_range(
"Index out of range");
125 return m_data[index];
136 if (index < 0 || index >= N) {
137 if (std::is_constant_evaluated()) {
138 throw "Compile-time error: Index out of range";
140 throw std::runtime_error(
"Index out of range");
143 return m_data[index];
153 constexpr const T&
at(
int index)
const {
154 if (index < 0 || index >= N) {
155 if (std::is_constant_evaluated()) {
156 throw "Compile-time error: Index out of range";
158 throw std::out_of_range(
"Index out of range");
161 return m_data[index];
172 for (
int i = 0; i < N; i++) result[i] = -m_data[i];
180 for (
int i = 0; i < N; i++) m_data[i] += rhs[i];
185 for (
int i = 0; i < N; i++) m_data[i] -= rhs[i];
190 for (
int i = 0; i < N; i++) m_data[i] *= rhs;
198 for (
int i = 0; i < N; i++) {
199 if (!
is_equal(m_data[i], rhs[i]))
return false;
206 return !(*
this == rhs);
226 for (
int i = 0; i < N; i++) {
227 if (!
is_equal(m_data[i], 0.0))
return false;
240 for (
int i = 0; i < N; i++) {
241 if (std::isnan(m_data[i]))
return true;
249 template<std::convertible_to<T> U>
252 if (std::is_constant_evaluated()) {
253 throw "Compile-time error: Division by zero";
255 throw std::runtime_error(
"Division by zero");
258 Float inv = 1.0 / value;
259 for (
int i = 0; i < N; i++) m_data[i] *= inv;
273 for (
int i = 0; i < N; i++)
274 result += m_data[i] * m_data[i];
298 if (std::is_constant_evaluated()) {
299 throw "Compile-time error: Cannot normalize a zero vector";
301 throw std::runtime_error(
"Cannot normalize a zero vector");
304 return result * (1.0 / len);
316 if (std::is_constant_evaluated()) {
317 throw "Compile-time error: Cannot normalize a zero vector";
319 throw std::runtime_error(
"Cannot normalize a zero vector");
322 return *
this *= (1.0 / len);
332 for (
int i = 0; i < N; i++) result += m_data[i] * rhs.m_data[i];
344 y() * rhs.z() -
z() * rhs.y(),
345 z() * rhs.x() -
x() * rhs.z(),
346 x() * rhs.y() -
y() * rhs.x()
350 constexpr T product() const noexcept {
352 for (
int i = 0; i < N; i++) result *= m_data[i];
360 void apply(
const std::function<
void(T&,
int)>& func) {
361 for (
int i = 0; i < N; ++i) func(m_data[i], i);
379 template<std::convertible_to<T> U>
382 result *=
static_cast<T
>(value);
387 template<std::convertible_to<T> U>
389 return rhs *
static_cast<T
>(lhs);
397 for (
int i = 0; i < N; i++) result[i] = (*
this)[i] * rhs[i];
404 template <std::convertible_to<T> U>
407 result /=
static_cast<T
>(rhs);
419 os <<
"Vec" << N <<
"(";
420 for (
int i = 0; i < N; ++i) {
421 os << vec[i] << (i == N - 1 ?
"" :
", ");
432 return std::max_element(m_data.begin(), m_data.end()) - m_data.begin();
440 return *std::max_element(m_data.begin(), m_data.end());
448 return std::min_element(m_data.begin(), m_data.end()) - m_data.begin();
456 return *std::min_element(m_data.begin(), m_data.end());
465 template<
typename ...Args>
466 requires (
sizeof...(Args) == N)
470 ((result[i++] = (*this)[args]), ...);
480 template<
typename ...Args>
481 requires (
sizeof...(Args) == N)
497template<
typename T,
int N>
499 if constexpr (base.
is_zero()) {
500 if (std::is_constant_evaluated()) {
501 throw "Base vector is zero, orthogonal bases are undefined.";
503 throw std::invalid_argument(
"Base vector is zero, orthogonal bases are undefined.");
519 if (std::is_constant_evaluated()) {
520 throw "Base vector is zero, orthogonal bases are undefined.";
522 throw std::invalid_argument(
"Base vector is zero, orthogonal bases are undefined.");
540 if (std::is_constant_evaluated()) {
541 throw "Base vector is zero, orthogonal bases are undefined.";
543 throw std::invalid_argument(
"Base vector is zero, orthogonal bases are undefined.");
549 if (std::abs(u.
x()) > std::abs(u.
y())) {
550 T inv_len = T(1) / std::sqrt(u.
x() * u.
x() + u.
z() * u.
z());
553 T inv_len = T(1) / std::sqrt(u.
y() * u.
y() + u.
z() * u.
z());
569template <
typename T,
int N>
Definition vector.hpp:570
A template class for N-dimensional mathematical vectors.
Definition vector.hpp:35
constexpr T & operator[](int index)
Provides mutable access to the vector's components by index.
Definition vector.hpp:135
constexpr Vector operator-(const Vector< T, N > &rhs) const noexcept
Subtracts one vector from another component-wise.
Definition vector.hpp:372
constexpr int max_dim() const
Returns the dimension with the maximum value.
Definition vector.hpp:431
static constexpr Vector zeros() noexcept
Creates a vector with all components set to zero.
Definition vector.hpp:56
constexpr const T & at(int index) const
Provides const access to the vector's components by index.
Definition vector.hpp:153
constexpr Vector operator*(U value) const noexcept
Multiplies a vector by a scalar.
Definition vector.hpp:380
constexpr bool operator!=(const Vector &rhs) const noexcept
operator!=
Definition vector.hpp:205
constexpr T & x() noexcept
Accesses the first component (x-axis).
Definition vector.hpp:88
constexpr const T & x() const noexcept
Const access to the first component (x-axis).
Definition vector.hpp:97
constexpr Vector & operator+=(const Vector &rhs) noexcept
Adds another vector to this one component-wise.
Definition vector.hpp:179
constexpr T & z() noexcept
Accesses the third component (z-axis).
Definition vector.hpp:92
constexpr Vector & normalize()
Normalizes this vector in-place, making its length 1.
Definition vector.hpp:313
constexpr T & w() noexcept
Accesses the fourth component (w-axis).
Definition vector.hpp:94
constexpr Vector() noexcept=default
Default constructor. Initializes all components to zero.
friend std::ostream & operator<<(std::ostream &os, const Vector &vec)
Stream insertion operator for printing the vector.
Definition vector.hpp:418
constexpr bool operator==(const Vector &rhs) const noexcept
operator== ,compare two vector component by component
Definition vector.hpp:197
constexpr bool is_normalized() const
Check if the vector is normalized.
Definition vector.hpp:215
constexpr T dot(const Vector &rhs) const noexcept
Calculates the dot product of this vector and another.
Definition vector.hpp:330
constexpr Vector cross(const Vector &rhs) const noexcept
Calculates the cross product of this vector and another.
Definition vector.hpp:342
constexpr Vector normalized() const
Returns a new vector that is a normalized version of this one.
Definition vector.hpp:294
constexpr Float length() const
Definition vector.hpp:283
constexpr T length_squared() const noexcept
Calculates the squared length (magnitude) of the vector.
Definition vector.hpp:271
constexpr Vector operator-() const noexcept
Negates the vector.
Definition vector.hpp:170
constexpr const T & y() const noexcept
Const access to the second component (y-axis).
Definition vector.hpp:99
constexpr T min() const
Returns the minimum value in the vector.
Definition vector.hpp:455
constexpr T & y() noexcept
Accesses the second component (y-axis).
Definition vector.hpp:90
constexpr const T & z() const noexcept
Const access to the third component (z-axis).
Definition vector.hpp:101
constexpr const T & operator[](int index) const
Provides const access to the vector's components by index.
Definition vector.hpp:117
constexpr Vector operator/=(const U &value) const noexcept
Divides this vector by a scalar.
Definition vector.hpp:250
friend constexpr Vector operator*(U lhs, const Vector< T, N > &rhs) noexcept
Multiplies a scalar by a vector.
Definition vector.hpp:388
constexpr Vector permuted(Args ...args) const
Returns a new vector with the specified dimensions permuted.
Definition vector.hpp:467
constexpr Vector operator/(U rhs) const
Divides a vector by a scalar.
Definition vector.hpp:405
constexpr bool is_zero() const
Check if all components of the vector are zero.
Definition vector.hpp:225
constexpr Vector & operator-=(const Vector &rhs) noexcept
Subtracts another vector from this one component-wise.
Definition vector.hpp:184
constexpr Vector & operator*=(const T &rhs) noexcept
Multiplies this vector by a scalar.
Definition vector.hpp:189
constexpr int dims() const noexcept
Returns the number of dimensions of the vector.
Definition vector.hpp:106
constexpr Vector operator*(const Vector< T, N > &rhs) const noexcept
Multiplies two vectors component-wise (Hadamard product).
Definition vector.hpp:395
constexpr bool has_nan() const
Check if any component of the vector is NaN (Not a Number).
Definition vector.hpp:239
constexpr Vector operator+(const Vector< T, N > &rhs) const noexcept
Adds two vectors component-wise.
Definition vector.hpp:365
static constexpr Vector ones() noexcept
Creates a vector with all components set to one.
Definition vector.hpp:62
constexpr T max() const
Returns the maximum value in the vector.
Definition vector.hpp:439
constexpr const T & w() const noexcept
Const access to the fourth component (w-axis).
Definition vector.hpp:103
constexpr int min_dim() const
Returns the dimension with the minimum value.
Definition vector.hpp:447
void apply(const std::function< void(T &, int)> &func)
Applies a function to each element of the vector.
Definition vector.hpp:360
constexpr Vector & permute(Args ...args)
Permutes the dimensions of the vector.
Definition vector.hpp:482
static constexpr Vector filled(T value) noexcept
Creates a vector with all components set to a single scalar value.
Definition vector.hpp:46
Provides basic, constexpr-aware mathematical functions.
Defines the primary floating-point type alias for the math library.
The namespace for math library implementation.
Definition bounding_box.hpp:9
constexpr T sqrt(T x)
Calculates the square root of a number with constexpr support.
Definition function.hpp:177
float Float
The primary floating-point type used throughout the math library.
Definition global.hpp:29
Normal< Float, 2 > Normal2
A 2-dimensional vector of type Float.
Definition vector.hpp:577
Vector< Float, 3 > Vec3
A 3-dimensional vector of type Float.
Definition vector.hpp:565
Vector< Float, 2 > Vec2
A 2-dimensional vector of type Float.
Definition vector.hpp:563
constexpr bool is_equal(T a, T b)
Compares two floating-point values for equality.
Definition function.hpp:287
Normal< Float, 3 > Normal3
A 3-dimensional vector of type Float.
Definition vector.hpp:579
Normal< Float, 4 > Normal4
A 4-dimensional vector of type Float.
Definition vector.hpp:581
Vector< Float, 4 > Vec4
A 4-dimensional vector of type Float.
Definition vector.hpp:567
constexpr std::vector< Vector< T, N > > get_orthogonal_bases(const Vector< T, N > &base)
Returns orthogonal bases for a given vector.
Definition vector.hpp:498