# vmath.hpp > C++17 tiny vector math library [![travis][badge.travis]][travis] [![appveyor][badge.appveyor]][appveyor] [![codecov][badge.codecov]][codecov] [![language][badge.language]][language] [![license][badge.license]][license] [![paypal][badge.paypal]][paypal] [badge.travis]: https://img.shields.io/travis/BlackMATov/vmath.hpp/main.svg?logo=travis [badge.appveyor]: https://img.shields.io/appveyor/ci/BlackMATov/vmath-hpp/main.svg?logo=appveyor [badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/vmath.hpp/main.svg?logo=codecov [badge.language]: https://img.shields.io/badge/language-C%2B%2B17-yellow.svg [badge.license]: https://img.shields.io/badge/license-MIT-blue.svg [badge.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C [travis]: https://travis-ci.org/BlackMATov/vmath.hpp [appveyor]: https://ci.appveyor.com/project/BlackMATov/vmath-hpp [codecov]: https://codecov.io/gh/BlackMATov/vmath.hpp [language]: https://en.wikipedia.org/wiki/C%2B%2B17 [license]: https://en.wikipedia.org/wiki/MIT_License [paypal]: https://www.paypal.me/matov [vmath]: https://github.com/BlackMATov/vmath.hpp ## Requirements - [gcc](https://www.gnu.org/software/gcc/) **>= 7** - [clang](https://clang.llvm.org/) **>= 5.0** - [msvc](https://visualstudio.microsoft.com/) **>= 2017** ## Installation [vmath.hpp][vmath] is a header-only library. All you need to do is copy the headers files from `headers` directory into your project and include them: ```cpp #include "vmath.hpp/vmath.hpp" ``` Also, you can add the root repository directory to your [cmake](https://cmake.org) project: ```cmake add_subdirectory(external/vmath.hpp) target_link_libraries(your_project_target vmath.hpp) ``` ## Disclaimer The [vmath.hpp][vmath] is a tiny vector math library mainly for games, game engines, and other graphics software. It will never be mathematically strict (e.g. the vector class has operator plus for adding scalars to a vector, which is convenient for developing CG applications but makes no sense in "real" math). For the same reason, the library does not provide flexible vector and matrix sizes. The library functions follow the same principles. Most functions and types are based on the HLSL ([High-Level Shading Language for DirectX](https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl)) specification. Matrices are row-major, which implies that vector, matrix multiplication is: v * M, not M * v. ## API - [Vector Types](#Vector-Types) - [Matrix Types](#Matrix-Types) - [Vector Operators](#Vector-Operators) - [Matrix Operators](#Matrix-Operators) - [Angle and Trigonometry Functions](#Angle-and-Trigonometry-Functions) - [Exponential Functions](#Exponential-Functions) - [Common Functions](#Common-Functions) - [Geometric Functions](#Geometric-Functions) - [Relational Functions](#Relational-Functions) - [Matrix Functions](#Matrix-Functions) - [Units](#Units) - [Cast](#Cast) - [Access](#Access) - [Matrix Transform 3D](#Matrix-Transform-3D) - [Matrix Transform 2D](#Matrix-Transform-2D) - [Matrix Projections](#Matrix-Projections) - [Vector Transform](#Vector-Transform) ### Vector Types ```cpp template < typename T, size_t Size > class vec_base; template < typename T > class vec_base { public: T x{}, y{}; constexpr vec_base() = default; constexpr explicit vec_base(T v); constexpr vec_base(T x, T y); constexpr explicit vec_base(const vec_base& xy); constexpr explicit vec_base(const vec_base& xy); }; template < typename T > class vec_base { public: T x{}, y{}, z{}; constexpr vec_base() = default; constexpr explicit vec_base(T v); constexpr vec_base(T x, T y, T z); constexpr vec_base(const vec_base& xy, T z); constexpr vec_base(T x, const vec_base& yz); constexpr explicit vec_base(const vec_base& xyz); }; template < typename T > class vec_base { public: T x{}, y{}, z{}, w{}; constexpr vec_base() = default; constexpr explicit vec_base(T v); constexpr vec_base(T x, T y, T z, T w); constexpr vec_base(const vec_base& xy, T z, T w); constexpr vec_base(T x, const vec_base& yz, T w); constexpr vec_base(T x, T y, const vec_base& zw); constexpr vec_base(const vec_base& xy, const vec_base& zw); constexpr vec_base(const vec_base& xyz, T w); constexpr vec_base(T x, const vec_base& yzw); }; template < typename T, size_t Size > class vec final : public vec_base { public: using component_type = T; using pointer = component_type*; using const_pointer = const component_type*; using reference = component_type&; using const_reference = const component_type&; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; static constexpr size_t size = Size; void swap(vec& other) noexcept(is_nothrow_swappable_v); iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_iterator end() const noexcept; reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; pointer data() noexcept; const_pointer data() const noexcept; constexpr reference at(size_t index); constexpr const_reference at(size_t index) const; constexpr reference operator[](size_t index) noexcept; constexpr const_reference operator[](size_t index) const noexcept; }; using bool2 = vec; using bool3 = vec; using bool4 = vec; using int2 = vec; using int3 = vec; using int4 = vec; using uint2 = vec; using uint3 = vec; using uint4 = vec; using float2 = vec; using float3 = vec; using float4 = vec; using double2 = vec; using double3 = vec; using double4 = vec; using size2 = vec; using size3 = vec; using size4 = vec; using ptrdiff2 = vec; using ptrdiff3 = vec; using ptrdiff4 = vec; ``` ### Matrix Types ```cpp template < typename T, size_t Size > class mat_base; template < typename T > class mat_base { public: using row_type = vec; row_type rows[2] = { {1, 0}, {0, 1}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); constexpr explicit mat_base(const row_type& d); constexpr mat_base( T m11, T m12, T m21, T m22); constexpr mat_base( const row_type& row0, const row_type& row1); constexpr explicit mat_base(const mat_base& other); constexpr explicit mat_base(const mat_base& other); }; template < typename T > class mat_base { public: using row_type = vec; row_type rows[3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); constexpr explicit mat_base(const row_type& d); constexpr mat_base( T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33); constexpr mat_base( const row_type& row0, const row_type& row1, const row_type& row2); constexpr mat_base( const mat_base& m, const vec_base& v); constexpr explicit mat_base(const mat_base& other); constexpr explicit mat_base(const mat_base& other); }; template < typename T > class mat_base { public: using row_type = vec; row_type rows[4] = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); constexpr explicit mat_base(const row_type& d); constexpr mat_base( T m11, T m12, T m13, T m14, T m21, T m22, T m23, T m24, T m31, T m32, T m33, T m34, T m41, T m42, T m43, T m44); constexpr mat_base( const row_type& row0, const row_type& row1, const row_type& row2, const row_type& row3); constexpr mat_base( const mat_base& m, const vec_base& v); constexpr explicit mat_base(const mat_base& other); constexpr explicit mat_base(const mat_base& other); }; template < typename T, size_t Size > class mat final : public mat_base { public: using row_type = vec; using pointer = row_type*; using const_pointer = const row_type*; using reference = row_type&; using const_reference = const row_type&; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; static constexpr size_t size = Size; void swap(mat& other) noexcept(is_nothrow_swappable_v); iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_iterator end() const noexcept; reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; pointer data() noexcept; const_pointer data() const noexcept; constexpr reference at(size_t index); constexpr const_reference at(size_t index) const; constexpr reference operator[](size_t index) noexcept; constexpr const_reference operator[](size_t index) const noexcept; }; using bool2x2 = mat; using bool3x3 = mat; using bool4x4 = mat; using int2x2 = mat; using int3x3 = mat; using int4x4 = mat; using uint2x2 = mat; using uint3x3 = mat; using uint4x4 = mat; using float2x2 = mat; using float3x3 = mat; using float4x4 = mat; using double2x2 = mat; using double3x3 = mat; using double4x4 = mat; using size2x2 = mat; using size3x3 = mat; using size4x4 = mat; using ptrdiff2x2 = mat; using ptrdiff3x3 = mat; using ptrdiff4x4 = mat; ``` ### Vector Operators ```cpp // -operator template < typename T, size_t Size > constexpr vec operator-(const vec& xs); // !operator template < typename T, std::size_t Size > constexpr vec operator!(const vec& xs); // operator+ template < typename T, size_t Size > constexpr vec operator+(const vec& xs, T y); template < typename T, size_t Size > constexpr vec operator+(T x, const vec& ys); template < typename T, size_t Size > constexpr vec operator+(const vec& xs, const vec& ys); // operator+= template < typename T, size_t Size > constexpr vec& operator+=(vec& xs, T y); template < typename T, size_t Size > constexpr vec& operator+=(vec& xs, const vec& ys); // operator- template < typename T, size_t Size > constexpr vec operator-(const vec& xs, T y); template < typename T, size_t Size > constexpr vec operator-(T x, const vec& ys); template < typename T, size_t Size > constexpr vec operator-(const vec& xs, const vec& ys); // operator-= template < typename T, size_t Size > constexpr vec& operator-=(vec& xs, T y); template < typename T, size_t Size > constexpr vec& operator-=(vec& xs, const vec& ys); // operator* template < typename T, size_t Size > constexpr vec operator*(const vec& xs, T y); template < typename T, size_t Size > constexpr vec operator*(T x, const vec& ys); template < typename T, size_t Size > constexpr vec operator*(const vec& xs, const vec& ys); // operator*= template < typename T, size_t Size > constexpr vec& operator*=(vec& xs, T y); template < typename T, size_t Size > constexpr vec& operator*=(vec& xs, const vec& ys); // operator/ template < typename T, size_t Size > constexpr vec operator/(const vec& xs, T y); template < typename T, size_t Size > constexpr vec operator/(T x, const vec& ys); template < typename T, size_t Size > constexpr vec operator/(const vec& xs, const vec& ys); // operator/= template < typename T, size_t Size > constexpr vec& operator/=(vec& xs, T y); template < typename T, size_t Size > constexpr vec& operator/=(vec& xs, const vec& ys); // operator== template < typename T, size_t Size > constexpr bool operator==(const vec& xs, const vec& ys); template < typename T, size_t Size > constexpr bool operator!=(const vec& xs, const vec& ys); // operator< template < typename T, size_t Size > constexpr bool operator<(const vec& xs, const vec& ys); ``` ### Matrix Operators ```cpp // -operator template < typename T, size_t Size > constexpr mat operator-(const mat& xs); // !operator template < typename T, size_t Size > constexpr mat operator!(const mat& xs); // operator+ template < typename T, size_t Size > constexpr mat operator+(const mat& xs, T y); template < typename T, size_t Size > constexpr mat operator+(T x, const mat& ys); template < typename T, size_t Size > constexpr mat operator+(const mat& xs, const mat& ys); // operator+= template < typename T, size_t Size > constexpr mat& operator+=(mat& xs, T y); template < typename T, size_t Size > constexpr mat& operator+=(mat& xs, const mat& ys); // operator- template < typename T, size_t Size > constexpr mat operator-(const mat& xs, T y); template < typename T, size_t Size > constexpr mat operator-(T x, const mat& ys); template < typename T, size_t Size > constexpr mat operator-(const mat& xs, const mat& ys); // operator-= template < typename T, size_t Size > constexpr mat& operator-=(mat& xs, T y); template < typename T, size_t Size > constexpr mat& operator-=(mat& xs, const mat& ys); // operator* template < typename T, size_t Size > constexpr mat operator*(const mat& xs, T y); template < typename T, size_t Size > constexpr mat operator*(T x, const mat& ys); template < typename T, size_t Size > constexpr vec operator*(const vec& xs, const mat& ys); template < typename T, size_t Size > constexpr mat operator*(const mat& xs, const mat& ys); // operator*= template < typename T, size_t Size > constexpr mat& operator*=(mat& xs, T y); template < typename T, size_t Size > constexpr vec& operator*=(vec& xs, const mat& ys); template < typename T, size_t Size > constexpr mat& operator*=(mat& xs, const mat& ys); // operator/ template < typename T, size_t Size > constexpr mat operator/(const mat& xs, T y); template < typename T, size_t Size > constexpr mat operator/(T x, const mat& ys); template < typename T, size_t Size > constexpr mat operator/(const mat& xs, const mat& ys); // operator/= template < typename T, size_t Size > constexpr mat& operator/=(mat& xs, T y); template < typename T, size_t Size > constexpr mat& operator/=(mat& xs, const mat& ys); // operator== template < typename T, size_t Size > constexpr bool operator==(const mat& xs, const mat& ys); template < typename T, size_t Size > constexpr bool operator!=(const mat& xs, const mat& ys); // operator< template < typename T, size_t Size > constexpr bool operator<(const mat& xs, const mat& ys); ``` ### Angle and Trigonometry Functions #### Scalar ```cpp template < floating_point T > constexpr T radians(T degrees) noexcept; template < floating_point T > constexpr T degrees(T radians) noexcept; template < floating_point T > T sin(T x) noexcept; template < floating_point T > T cos(T x) noexcept; template < floating_point T > T tan(T x) noexcept; template < floating_point T > T asin(T x) noexcept; template < floating_point T > T acos(T x) noexcept; template < floating_point T > T atan(T x) noexcept; template < floating_point T > T atan2(T y, T x) noexcept; template < floating_point T > T sinh(T x) noexcept; template < floating_point T > T cosh(T x) noexcept; template < floating_point T > T tanh(T x) noexcept; template < floating_point T > T asinh(T x) noexcept; template < floating_point T > T acosh(T x) noexcept; template < floating_point T > T atanh(T x) noexcept; template < floating_point T > std::pair sincos(T x) noexcept; template < floating_point T > void sincos(T x, T* s, T* c) noexcept; ``` #### Vector ```cpp template < typename T, size_t Size > constexpr vec radians(const vec& degrees); template < typename T, size_t Size > constexpr vec degrees(const vec& radians); template < typename T, size_t Size > vec sin(const vec& xs); template < typename T, size_t Size > vec cos(const vec& xs); template < typename T, size_t Size > vec tan(const vec& xs); template < typename T, size_t Size > vec asin(const vec& xs); template < typename T, size_t Size > vec acos(const vec& xs); template < typename T, size_t Size > vec atan(const vec& xs); template < typename T, size_t Size > vec atan2(const vec& ys, const vec& xs); template < typename T, size_t Size > vec sinh(const vec& xs); template < typename T, size_t Size > vec cosh(const vec& xs); template < typename T, size_t Size > vec tanh(const vec& xs); template < typename T, size_t Size > vec asinh(const vec& xs); template < typename T, size_t Size > vec acosh(const vec& xs); template < typename T, size_t Size > vec atanh(const vec& xs); template < typename T, size_t Size > void sincos(const vec& xs, vec* ss, vec* cs); ``` ### Exponential Functions #### Scalar ```cpp template < floating_point T > T pow(T x, T y) noexcept; template < floating_point T > T exp(T x) noexcept; template < floating_point T > T log(T x) noexcept; template < floating_point T > T exp2(T x) noexcept; template < floating_point T > T log2(T x) noexcept; template < floating_point T > T sqrt(T x) noexcept; template < floating_point T > T rsqrt(T x) noexcept; ``` #### Vector ```cpp template < typename T, size_t Size > vec pow(const vec& xs, const vec& ys); template < typename T, size_t Size > vec exp(const vec& xs); template < typename T, size_t Size > vec log(const vec& xs); template < typename T, size_t Size > vec exp2(const vec& xs); template < typename T, size_t Size > vec log2(const vec& xs); template < typename T, size_t Size > vec sqrt(const vec& xs); template < typename T, size_t Size > vec rsqrt(const vec& xs); ``` ### Common Functions #### Scalar ```cpp template < arithmetic T > constexpr T abs(T x) noexcept; template < arithmetic T > constexpr T sign(T x) noexcept; template < floating_point T > constexpr T reciprocal(T x) noexcept; template < floating_point T > T floor(T x) noexcept; template < floating_point T > T trunc(T x) noexcept; template < floating_point T > T round(T x) noexcept; template < floating_point T > T ceil(T x) noexcept; template < floating_point T > T fract(T x) noexcept; template < floating_point T > T fmod(T x, T y) noexcept; template < floating_point T > T modf(T x, T* y) noexcept; template < arithmetic T > constexpr T min(T x, T y) noexcept; template < arithmetic T, arithmetic... Ts > constexpr std::common_type_t min(T x, T y, Ts... ts) noexcept; template < arithmetic T > constexpr T max(T x, T y) noexcept; template < arithmetic T, arithmetic... Ts > constexpr std::common_type_t max(T x, T y, Ts... ts) noexcept; template < arithmetic T > constexpr T clamp(T x, T min_x, T max_x) noexcept; template < arithmetic T > constexpr T saturate(T x) noexcept; template < floating_point T > constexpr T lerp(T x, T y, T a) noexcept; template < floating_point T > constexpr T step(T edge, T x) noexcept; template < floating_point T > constexpr T smoothstep(T edge0, T edge1, T x) noexcept; template < arithmetic T > bool isnan(T x) noexcept; template < arithmetic T > bool isinf(T x) noexcept; template < arithmetic T > bool isfinite(T x) noexcept; template < floating_point T > T fma(T x, T y, T z) noexcept; template < floating_point T > T frexp(T x, int* exp) noexcept; template < floating_point T > T ldexp(T x, int exp) noexcept; ``` #### Vector ```cpp template < typename T, size_t Size > constexpr vec abs(const vec& xs); template < typename T, size_t Size > constexpr vec sign(const vec& xs); template < typename T, size_t Size > constexpr vec reciprocal(const vec& xs); template < typename T, size_t Size > vec floor(const vec& xs); template < typename T, size_t Size > vec trunc(const vec& xs); template < typename T, size_t Size > vec round(const vec& xs); template < typename T, size_t Size > vec ceil(const vec& xs); template < typename T, size_t Size > vec fract(const vec& xs); template < typename T, size_t Size > vec fmod(const vec& xs, T y); template < typename T, size_t Size > vec fmod(const vec& xs, const vec& ys); template < typename T, size_t Size > vec modf(const vec& xs, vec* is); template < typename T, size_t Size > constexpr T min(const vec& xs); template < typename T, size_t Size > constexpr vec min(const vec& xs, T y); template < typename T, size_t Size > constexpr vec min(const vec& xs, const vec& ys); template < typename T, size_t Size > constexpr T max(const vec& xs); template < typename T, size_t Size > constexpr vec max(const vec& xs, T y); template < typename T, size_t Size > constexpr vec max(const vec& xs, const vec& ys); template < typename T, size_t Size > constexpr vec clamp(const vec& xs, T min_x, T max_x); template < typename T, size_t Size > constexpr vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs); template < typename T, size_t Size > constexpr vec saturate(const vec& xs); template < typename T, size_t Size > constexpr vec lerp(const vec& xs, const vec& ys, T a); template < typename T, size_t Size > constexpr vec lerp(const vec& xs, const vec& ys, const vec& as); template < typename T, size_t Size > constexpr vec step(T edge, const vec& xs); template < typename T, size_t Size > constexpr vec step(const vec& edges, const vec& xs); template < typename T, size_t Size > constexpr vec smoothstep(T edge0, T edge1, const vec& xs); template < typename T, size_t Size > constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); template < typename T, size_t Size > vec isnan(const vec& xs); template < typename T, size_t Size > vec isinf(const vec& xs); template < typename T, size_t Size > vec isfinite(const vec& xs); template < typename T, size_t Size > vec fma(const vec& as, const vec& bs, const vec& cs); template < typename T, size_t Size > vec frexp(const vec& xs, vec* exps); template < typename T, size_t Size > vec ldexp(const vec& xs, const vec& exps); ``` ### Geometric Functions #### Scalar ```cpp template < arithmetic T > constexpr T dot(T x, T y) noexcept; template < arithmetic T > constexpr T length(T x) noexcept; template < arithmetic T > constexpr T length2(T x) noexcept; template < arithmetic T > constexpr T distance(T x, T y) noexcept; template < arithmetic T > constexpr T distance2(T x, T y) noexcept; template < floating_point T > T normalize(T x) noexcept; template < floating_point T > constexpr T faceforward(T n, T i, T nref) noexcept; template < floating_point T > constexpr T reflect(T i, T n) noexcept; template < floating_point T > T refract(T i, T n, T eta) noexcept; ``` #### Vector ```cpp template < typename T, size_t Size > constexpr T dot(const vec& xs, const vec& ys); template < typename T, size_t Size > T length(const vec& xs); template < typename T, size_t Size > constexpr T length2(const vec& xs); template < typename T, size_t Size > T distance(const vec& xs, const vec& ys); template < typename T, size_t Size > constexpr T distance2(const vec& xs, const vec& ys); template < typename T > constexpr T cross(const vec& xs, const vec& ys); template < typename T > constexpr vec cross(const vec& xs, const vec& ys); template < typename T, size_t Size > vec normalize(const vec& xs); template < typename T, size_t Size > constexpr vec faceforward(const vec& n, const vec& i, const vec& nref); template < typename T, size_t Size > constexpr vec reflect(const vec& i, const vec& n); template < typename T, size_t Size > vec refract(const vec& i, const vec& n, T eta); ``` ### Relational Functions #### Scalar ```cpp template < arithmetic T > constexpr bool less(T x, T y) noexcept; template < arithmetic T > constexpr bool less_equal(T x, T y) noexcept; template < arithmetic T > constexpr bool greater(T x, T y) noexcept; template < arithmetic T > constexpr bool greater_equal(T x, T y) noexcept; template < arithmetic T > constexpr bool equal_to(T x, T y) noexcept; template < arithmetic T > constexpr bool equal_to(T x, T y, T epsilon) noexcept; template < arithmetic T > constexpr bool not_equal_to(T x, T y) noexcept; template < arithmetic T > constexpr bool not_equal_to(T x, T y, T epsilon) noexcept; template < arithmetic T > constexpr bool any(T x) noexcept; template < arithmetic T > constexpr bool all(T x) noexcept; ``` #### Vector ```cpp template < typename T, std::size_t Size > constexpr vec less(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec less(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec less(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec less_equal(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec less_equal(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec less_equal(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec greater(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec greater(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec greater(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec greater_equal(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec greater_equal(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec greater_equal(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec equal_to(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, T y, T epsilon); template < typename T, std::size_t Size > constexpr vec equal_to(T x, const vec& ys, T epsilon); template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, const vec& ys, T epsilon); template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, T y); template < typename T, std::size_t Size > constexpr vec not_equal_to(T x, const vec& ys); template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, const vec& ys); template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, T y, T epsilon); template < typename T, std::size_t Size > constexpr vec not_equal_to(T x, const vec& ys, T epsilon); template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, const vec& ys, T epsilon); template < typename T, size_t Size > constexpr bool any(const vec& xs); template < typename T, size_t Size > constexpr bool all(const vec& xs); ``` ### Matrix Functions ```cpp template < typename T > constexpr mat transpose(const mat& m); template < typename T > constexpr mat transpose(const mat& m); template < typename T > constexpr mat transpose(const mat& m); template < typename T > constexpr T determinant(const mat& m); template < typename T > constexpr T determinant(const mat& m); template < typename T > constexpr T determinant(const mat& m); template < typename T > constexpr mat inverse(const mat& m); template < typename T > constexpr mat inverse(const mat& m); template < typename T > constexpr mat inverse(const mat& m); ``` ### Units ```cpp template < typename T > inline constexpr vec zero2; template < typename T > inline constexpr vec zero3; template < typename T > inline constexpr vec zero4; template < typename T > inline constexpr vec unit2; template < typename T > inline constexpr vec unit3; template < typename T > inline constexpr vec unit4; template < typename T > inline constexpr vec unit2_x; template < typename T > inline constexpr vec unit2_y; template < typename T > inline constexpr vec unit3_x; template < typename T > inline constexpr vec unit3_y; template < typename T > inline constexpr vec unit3_z; template < typename T > inline constexpr vec unit4_x; template < typename T > inline constexpr vec unit4_y; template < typename T > inline constexpr vec unit4_z; template < typename T > inline constexpr vec unit4_w; template < typename T > inline constexpr mat zero2x2; template < typename T > inline constexpr mat zero3x3; template < typename T > inline constexpr mat zero4x4; template < typename T > inline constexpr mat unit2x2; template < typename T > inline constexpr mat unit3x3; template < typename T > inline constexpr mat unit4x4; template < typename T > inline constexpr mat identity2x2; template < typename T > inline constexpr mat identity3x3; template < typename T > inline constexpr mat identity4x4; ``` ### Cast ```cpp template < arithmetic To, arithmetic From > constexpr To cast_to(From x) noexcept; template < typename To, typename From, size_t Size > constexpr vec cast_to(const vec& v); template < typename To, typename From, size_t Size > constexpr mat cast_to(const mat& m); ``` ### Access ```cpp template < typename T, size_t Size > constexpr T component(const vec& v, size_t index); template < typename T, size_t Size > constexpr vec component(vec v, size_t index, T x); template < typename T, size_t Size > constexpr vec row(const mat& m, size_t index); template < typename T, size_t Size > constexpr mat row(mat m, size_t index, const vec& v); template < typename T, size_t Size > constexpr vec column(const mat& m, size_t index); template < typename T, size_t Size > constexpr mat column(const mat& m, size_t index, const vec& v); ``` ### Matrix Transform 3D ```cpp template < typename T > constexpr mat translate(T x, T y, T z); template < typename T > constexpr mat translate(const vec& v); template < typename T > constexpr mat translate(const mat& m, T x, T y, T z); template < typename T > constexpr mat translate(const mat& m, const vec& v); template < typename T > mat rotate(T angle, const vec& axis); template < typename T > mat rotate(const mat& m, T angle, const vec& axis); template < typename T > mat rotate_x(T angle); template < typename T > mat rotate_x(const mat& m, T angle); template < typename T > mat rotate_y(T angle); template < typename T > mat rotate_y(const mat& m, T angle); template < typename T > mat rotate_z(T angle); template < typename T > mat rotate_z(const mat& m, T angle); template < typename T > constexpr mat scale(T x, T y, T z); template < typename T > constexpr mat scale(const vec& v); template < typename T > constexpr mat scale(const mat& m, T x, T y, T z); template < typename T > constexpr mat scale(const mat& m, const vec& v); template < typename T > mat look_at_lh(const vec& eye, const vec& at, const vec& up); template < typename T > mat look_at_rh(const vec& eye, const vec& at, const vec& up); ``` ### Matrix Transform 2D ```cpp template < typename T > constexpr mat translate(T x, T y); template < typename T > constexpr mat translate(const vec& v); template < typename T > constexpr mat translate(const mat& m, T x, T y); template < typename T > constexpr mat translate(const mat& m, const vec& v); template < typename T > mat rotate(T angle); template < typename T > mat rotate(const mat& m, T angle); template < typename T > constexpr mat scale(T x, T y); template < typename T > constexpr mat scale(const vec& v); template < typename T > constexpr mat scale(const mat& m, T x, T y); template < typename T > constexpr mat scale(const mat& m, const vec& v); template < typename T > constexpr mat shear(T x, T y); template < typename T > constexpr mat shear(const vec& v); template < typename T > constexpr mat shear(const mat& m, T x, T y); template < typename T > constexpr mat shear(const mat& m, const vec& v); template < typename T > constexpr mat shear_x(T y); template < typename T > constexpr mat shear_x(const mat& m, T y); template < typename T > constexpr mat shear_y(T x); template < typename T > constexpr mat shear_y(const mat& m, T x); ``` ### Matrix Projections ```cpp template < typename T > mat orthographic_lh_zo(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat orthographic_lh_no(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat orthographic_rh_zo(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat orthographic_rh_no(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat perspective_lh_zo(T fov, T aspect, T znear, T zfar); template < typename T > mat perspective_lh_no(T fov, T aspect, T znear, T zfar); template < typename T > mat perspective_rh_zo(T fov, T aspect, T znear, T zfar); template < typename T > mat perspective_rh_no(T fov, T aspect, T znear, T zfar); ``` ### Vector Transform ```cpp template < typename T, size_t Size > T angle(const vec& x, const vec& y); template < typename T > vec rotate(const vec& v, T angle); template < typename T > vec rotate(const vec& v, T angle, const vec& normal); template < typename T > vec rotate(const vec& v, T angle, const vec& normal); template < typename T, std::size_t Size > vec project(const vec& v, const vec& normal); ``` ## [License (MIT)](./LICENSE.md)