# vmath.hpp > C++17 tiny vector math library [![linux][badge.linux]][linux] [![darwin][badge.darwin]][darwin] [![windows][badge.windows]][windows] [![language][badge.language]][language] [![license][badge.license]][license] [badge.darwin]: https://img.shields.io/github/actions/workflow/status/BlackMATov/vmath.hpp/.github/workflows/darwin.yml?label=Xcode&logo=xcode [badge.linux]: https://img.shields.io/github/actions/workflow/status/BlackMATov/vmath.hpp/.github/workflows/linux.yml?label=GCC%2FClang&logo=linux [badge.windows]: https://img.shields.io/github/actions/workflow/status/BlackMATov/vmath.hpp/.github/workflows/windows.yml?label=Visual%20Studio&logo=visual-studio [badge.language]: https://img.shields.io/badge/language-C%2B%2B17-yellow [badge.license]: https://img.shields.io/badge/license-MIT-blue [darwin]: https://github.com/BlackMATov/vmath.hpp/actions?query=workflow%3Adarwin [linux]: https://github.com/BlackMATov/vmath.hpp/actions?query=workflow%3Alinux [windows]: https://github.com/BlackMATov/vmath.hpp/actions?query=workflow%3Awindows [language]: https://en.wikipedia.org/wiki/C%2B%2B17 [license]: https://en.wikipedia.org/wiki/MIT_License [vmath]: https://github.com/BlackMATov/vmath.hpp ## Requirements - [clang](https://clang.llvm.org/) **>= 7** - [gcc](https://www.gnu.org/software/gcc/) **>= 7** - [msvc](https://visualstudio.microsoft.com/) **>= 2019** - [xcode](https://developer.apple.com/xcode/) **>= 11.7** ## 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_all.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 PUBLIC vmath.hpp::vmath.hpp) ``` Or just use the single-header version of the library, which you can find [here](develop/singles/headers/vmath.hpp/vmath_all.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) - [Quaternion Types](#Quaternion-Types) - [Vector Operators](#Vector-Operators) - [Matrix Operators](#Matrix-Operators) - [Quaternion Operators](#Quaternion-Operators) - [Common Functions](#Common-Functions) - [Angle and Trigonometric Functions](#Angle-and-Trigonometric-Functions) - [Exponential Functions](#Exponential-Functions) - [Geometric Functions](#Geometric-Functions) - [Relational Functions](#Relational-Functions) - [Matrix Functions](#Matrix-Functions) - [Quaternion Functions](#Quaternion-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) - [Quaternion Transform](#Quaternion-Transform) ### Vector Types ```cpp template < typename T, size_t Size > class vec_base; template < typename T > class vec_base { public: T x, y; vec_base(); vec_base(no_init_t); vec_base(zero_init_t); vec_base(unit_init_t); explicit vec_base(T v); vec_base(T x, T y); template < typename U > vec_base(const vec_base& other); template < typename U > explicit vec_base(const vec_base& other); template < typename U > explicit vec_base(const vec_base& other); template < typename U > explicit vec_base(const U* p); }; template < typename T > class vec_base { public: T x, y, z; vec_base(); vec_base(no_init_t); vec_base(zero_init_t); vec_base(unit_init_t); explicit vec_base(T v); vec_base(T x, T y, T z); vec_base(const vec_base& xy, T z); vec_base(T x, const vec_base& yz); template < typename U > vec_base(const vec_base& other); template < typename U > explicit vec_base(const vec_base& other); template < typename U > explicit vec_base(const U* p); }; template < typename T > class vec_base { public: T x, y, z, w; vec_base(); vec_base(no_init_t); vec_base(zero_init_t); vec_base(unit_init_t); explicit vec_base(T v); vec_base(T x, T y, T z, T w); vec_base(const vec_base& xy, T z, T w); vec_base(T x, const vec_base& yz, T w); vec_base(T x, T y, const vec_base& zw); vec_base(const vec_base& xy, const vec_base& zw); vec_base(const vec_base& xyz, T w); vec_base(T x, const vec_base& yzw); template < typename U > vec_base(const vec_base& other); template < typename U > explicit vec_base(const U* p); }; template < typename T, size_t Size > class vec final : public vec_base { public: using self_type = vec; using base_type = vec_base; 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 inline size_t size = Size; void swap(vec& other); iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; const_iterator cbegin() const; const_iterator cend() const; const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; pointer data(); const_pointer data() const; reference at(size_t index); const_reference at(size_t index) const; reference operator[](size_t index); const_reference operator[](size_t index) const; }; using bvec2 = vec; using bvec3 = vec; using bvec4 = vec; using ivec2 = vec; using ivec3 = vec; using ivec4 = vec; using uvec2 = vec; using uvec3 = vec; using uvec4 = vec; using fvec2 = vec; using fvec3 = vec; using fvec4 = vec; using dvec2 = vec; using dvec3 = vec; using dvec4 = 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]; mat_base(); mat_base(no_init_t); mat_base(zero_init_t); mat_base(unit_init_t); mat_base(identity_init_t); explicit mat_base(T d); explicit mat_base(const row_type& d); mat_base( T m11, T m12, T m21, T m22); mat_base( const row_type& row0, const row_type& row1); template < typename U > mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const U* p); }; template < typename T > class mat_base { public: using row_type = vec; row_type rows[3]; mat_base(); mat_base(no_init_t); mat_base(zero_init_t); mat_base(unit_init_t); mat_base(identity_init_t); explicit mat_base(T d); explicit mat_base(const row_type& d); mat_base( T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33); mat_base( const row_type& row0, const row_type& row1, const row_type& row2); mat_base( const mat_base& m, const vec_base& v); template < typename U > mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const U* p); }; template < typename T > class mat_base { public: using row_type = vec; row_type rows[4]; mat_base(); mat_base(no_init_t); mat_base(zero_init_t); mat_base(unit_init_t); mat_base(identity_init_t); explicit mat_base(T d); explicit mat_base(const row_type& d); 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); mat_base( const row_type& row0, const row_type& row1, const row_type& row2, const row_type& row3); mat_base( const mat_base& m, const vec_base& v); template < typename U > mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const mat_base& other); template < typename U > explicit mat_base(const U* p); }; template < typename T, size_t Size > class mat final : public mat_base { public: using self_type = mat; using base_type = mat_base; using component_type = T; 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 inline size_t size = Size; void swap(mat& other); iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; const_iterator cbegin() const; const_iterator cend() const; const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; pointer data(); const_pointer data() const; reference at(size_t index); const_reference at(size_t index) const; reference operator[](size_t index); const_reference operator[](size_t index) const; }; using bmat2 = mat; using bmat3 = mat; using bmat4 = mat; using imat2 = mat; using imat3 = mat; using imat4 = mat; using umat2 = mat; using umat3 = mat; using umat4 = mat; using fmat2 = mat; using fmat3 = mat; using fmat4 = mat; using dmat2 = mat; using dmat3 = mat; using dmat4 = mat; ``` ### Quaternion Types ```cpp template < typename T > class qua_base { public: vec v; T s; qua_base(); qua_base(no_init_t); qua_base(zero_init_t); qua_base(identity_init_t); qua_base(T vx, T vy, T vz, T s); qua_base(const vec& v, T s); explicit qua_base(const vec& vs); template < typename U > qua_base(const qua_base& other); template < typename U > explicit operator vec() const; template < typename U > explicit qua_base(const U* p); }; template < typename T > class qua final { public: using self_type = qua; using base_type = qua_base; using component_type = T; using imag_type = vec; using real_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 inline size_t size = 4; void swap(qua& other); iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; const_iterator cbegin() const; const_iterator cend() const; const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; pointer data(); const_pointer data() const; reference at(size_t index); const_reference at(size_t index) const; reference operator[](size_t index); const_reference operator[](size_t index) const; }; using fqua = qua; using dqua = qua; ``` ### Vector Operators ```cpp // +operator template < typename T, size_t Size > auto operator+(const vec& xs); // -operator template < typename T, size_t Size > auto operator-(const vec& xs); // ~operator template < typename T, size_t Size > auto operator~(const vec& xs); // !operator template < typename T, size_t Size > auto operator!(const vec& xs); // ++operator template < typename T, size_t Size > vec& operator++(vec& xs); // --operator template < typename T, size_t Size > vec& operator--(vec& xs); // operator++ template < typename T, size_t Size > vec operator++(vec& xs, int); // operator-- template < typename T, size_t Size > vec operator--(vec& xs, int); // operator+ template < typename T, typename U, size_t Size > auto operator+(const vec& xs, U y); template < typename T, typename U, size_t Size > auto operator+(T x, const vec& ys); template < typename T, typename U, size_t Size > auto operator+(const vec& xs, const vec& ys); // operator+= template < typename T, size_t Size > vec& operator+=(vec& xs, T y); template < typename T, size_t Size > vec& operator+=(vec& xs, const vec& ys); // operator- template < typename T, typename U, size_t Size > auto operator-(const vec& xs, U y); template < typename T, typename U, size_t Size > auto operator-(T x, const vec& ys); template < typename T, typename U, size_t Size > auto operator-(const vec& xs, const vec& ys); // operator-= template < typename T, size_t Size > vec& operator-=(vec& xs, T y); template < typename T, size_t Size > vec& operator-=(vec& xs, const vec& ys); // operator* template < typename T, typename U, size_t Size > auto operator*(const vec& xs, U y); template < typename T, typename U, size_t Size > auto operator*(T x, const vec& ys); template < typename T, typename U, size_t Size > auto operator*(const vec& xs, const vec& ys); // operator*= template < typename T, size_t Size > vec& operator*=(vec& xs, T y); template < typename T, size_t Size > vec& operator*=(vec& xs, const vec& ys); // operator/ template < typename T, typename U, size_t Size > auto operator/(const vec& xs, U y); template < typename T, typename U, size_t Size > auto operator/(T x, const vec& ys); template < typename T, typename U, size_t Size > auto operator/(const vec& xs, const vec& ys); // operator/= template < typename T, size_t Size > vec& operator/=(vec& xs, T y); template < typename T, size_t Size > vec& operator/=(vec& xs, const vec& ys); // operator& template < typename T, size_t Size > auto operator&(const vec& xs, T y); template < typename T, size_t Size > auto operator&(T x, const vec& ys); template < typename T, size_t Size > auto operator&(const vec& xs, const vec& ys); // operator&= template < typename T, size_t Size > vec& operator&=(vec& xs, T y); template < typename T, size_t Size > vec& operator&=(vec& xs, const vec& ys); // operator| template < typename T, size_t Size > auto operator|(const vec& xs, T y); template < typename T, size_t Size > auto operator|(T x, const vec& ys); template < typename T, size_t Size > auto operator|(const vec& xs, const vec& ys); // operator|= template < typename T, size_t Size > vec& operator|=(vec& xs, T y); template < typename T, size_t Size > vec& operator|=(vec& xs, const vec& ys); // operator^ template < typename T, size_t Size > auto operator^(const vec& xs, T y); template < typename T, size_t Size > auto operator^(T x, const vec& ys); template < typename T, size_t Size > auto operator^(const vec& xs, const vec& ys); // operator^= template < typename T, size_t Size > vec& operator^=(vec& xs, T y); template < typename T, size_t Size > vec& operator^=(vec& xs, const vec& ys); // operator<< template < typename T, size_t Size > auto operator<<(const vec& xs, T y); template < typename T, size_t Size > auto operator<<(T x, const vec& ys); template < typename T, size_t Size > auto operator<<(const vec& xs, const vec& ys); // operator<<= template < typename T, size_t Size > vec& operator<<=(vec& xs, T y); template < typename T, size_t Size > vec& operator<<=(vec& xs, const vec& ys); // operator>> template < typename T, size_t Size > auto operator>>(const vec& xs, T y); template < typename T, size_t Size > auto operator>>(T x, const vec& ys); template < typename T, size_t Size > auto operator>>(const vec& xs, const vec& ys); // operator>>= template < typename T, size_t Size > vec& operator>>=(vec& xs, T y); template < typename T, size_t Size > vec& operator>>=(vec& xs, const vec& ys); // operator&& template < typename T, size_t Size > auto operator&&(const vec& xs, T y); template < typename T, size_t Size > auto operator&&(T x, const vec& ys); template < typename T, size_t Size > auto operator&&(const vec& xs, const vec& ys); // operator|| template < typename T, size_t Size > auto operator||(const vec& xs, T y); template < typename T, size_t Size > auto operator||(T x, const vec& ys); template < typename T, size_t Size > auto operator||(const vec& xs, const vec& ys); // operator== template < typename T, size_t Size > bool operator==(const vec& xs, const vec& ys); // operator!= template < typename T, size_t Size > bool operator!=(const vec& xs, const vec& ys); // operator< template < typename T, size_t Size > bool operator<(const vec& xs, const vec& ys); ``` ### Matrix Operators ```cpp // +operator template < typename T, size_t Size > auto operator+(const mat& xs); // -operator template < typename T, size_t Size > auto operator-(const mat& xs); // ~operator template < typename T, size_t Size > auto operator~(const mat& xs); // !operator template < typename T, size_t Size > auto operator!(const mat& xs); // ++operator template < typename T, size_t Size > mat& operator++(mat& xs); // --operator template < typename T, size_t Size > mat& operator--(mat& xs); // operator++ template < typename T, size_t Size > mat operator++(mat& xs, int); // operator-- template < typename T, size_t Size > mat operator--(mat& xs, int); // operator+ template < typename T, typename U, size_t Size > auto operator+(const mat& xs, U y); template < typename T, typename U, size_t Size > auto operator+(T x, const mat& ys); template < typename T, typename U, size_t Size > auto operator+(const mat& xs, const mat& ys); // operator+= template < typename T, size_t Size > mat& operator+=(mat& xs, T y); template < typename T, size_t Size > mat& operator+=(mat& xs, const mat& ys); // operator- template < typename T, typename U, size_t Size > auto operator-(const mat& xs, U y); template < typename T, typename U, size_t Size > auto operator-(T x, const mat& ys); template < typename T, typename U, size_t Size > auto operator-(const mat& xs, const mat& ys); // operator-= template < typename T, size_t Size > mat& operator-=(mat& xs, T y); template < typename T, size_t Size > mat& operator-=(mat& xs, const mat& ys); // operator* template < typename T, typename U, size_t Size > auto operator*(const mat& xs, U y); template < typename T, typename U, size_t Size > auto operator*(T x, const mat& ys); template < typename T, typename U, size_t Size > auto operator*(const vec& xs, const mat& ys); template < typename T, typename U, size_t Size > auto operator*(const mat& xs, const mat& ys); // operator*= template < typename T, size_t Size > mat& operator*=(mat& xs, T y); template < typename T, size_t Size > vec& operator*=(vec& xs, const mat& ys); template < typename T, size_t Size > mat& operator*=(mat& xs, const mat& ys); // operator/ template < typename T, typename U, size_t Size > auto operator/(const mat& xs, U y); template < typename T, typename U, size_t Size > auto operator/(T x, const mat& ys); // operator/= template < typename T, size_t Size > mat& operator/=(mat& xs, T y); // operator& template < typename T, size_t Size > auto operator&(const mat& xs, T y); template < typename T, size_t Size > auto operator&(T x, const mat& ys); template < typename T, size_t Size > auto operator&(const mat& xs, const mat& ys); // operator&= template < typename T, size_t Size > mat& operator&=(mat& xs, T y); template < typename T, size_t Size > mat& operator&=(mat& xs, const mat& ys); // operator| template < typename T, size_t Size > auto operator|(const mat& xs, T y); template < typename T, size_t Size > auto operator|(T x, const mat& ys); template < typename T, size_t Size > auto operator|(const mat& xs, const mat& ys); // operator|= template < typename T, size_t Size > mat& operator|=(mat& xs, T y); template < typename T, size_t Size > mat& operator|=(mat& xs, const mat& ys); // operator^ template < typename T, size_t Size > auto operator^(const mat& xs, T y); template < typename T, size_t Size > auto operator^(T x, const mat& ys); template < typename T, size_t Size > auto operator^(const mat& xs, const mat& ys); // operator^= template < typename T, size_t Size > mat& operator^=(mat& xs, T y); template < typename T, size_t Size > mat& operator^=(mat& xs, const mat& ys); // operator<< template < typename T, size_t Size > auto operator<<(const mat& xs, T y); template < typename T, size_t Size > auto operator<<(T x, const mat& ys); template < typename T, size_t Size > auto operator<<(const mat& xs, const mat& ys); // operator<<= template < typename T, size_t Size > mat& operator<<=(mat& xs, T y); template < typename T, size_t Size > mat& operator<<=(mat& xs, const mat& ys); // operator>> template < typename T, size_t Size > auto operator>>(const mat& xs, T y); template < typename T, size_t Size > auto operator>>(T x, const mat& ys); template < typename T, size_t Size > auto operator>>(const mat& xs, const mat& ys); // operator>>= template < typename T, size_t Size > mat& operator>>=(mat& xs, T y); template < typename T, size_t Size > mat& operator>>=(mat& xs, const mat& ys); // operator&& template < typename T, size_t Size > auto operator&&(const mat& xs, T y); template < typename T, size_t Size > auto operator&&(T x, const mat& ys); template < typename T, size_t Size > auto operator&&(const mat& xs, const mat& ys); // operator|| template < typename T, size_t Size > auto operator||(const mat& xs, T y); template < typename T, size_t Size > auto operator||(T x, const mat& ys); template < typename T, size_t Size > auto operator||(const mat& xs, const mat& ys); // operator== template < typename T, size_t Size > bool operator==(const mat& xs, const mat& ys); // operator!= template < typename T, size_t Size > bool operator!=(const mat& xs, const mat& ys); // operator< template < typename T, size_t Size > bool operator<(const mat& xs, const mat& ys); ``` ### Quaternion Operators ```cpp // +operator template < typename T > auto operator+(const qua& xs); // -operator template < typename T > auto operator-(const qua& xs); // operator+ template < typename T, typename U > auto operator+(const qua& xs, const qua& ys); // operator+= template < typename T > qua& operator+=(qua& xs, const qua& ys); // operator- template < typename T, typename U > auto operator-(const qua& xs, const qua& ys); // operator-= template < typename T > qua& operator-=(qua& xs, const qua& ys); // operator* template < typename T, typename U > auto operator*(const qua& xs, U y); template < typename T, typename U > auto operator*(T x, const qua& ys); template < typename T, typename U > auto operator*(const vec& xs, const qua& ys); template < typename T, typename U > auto operator*(const qua& xs, const qua& ys); // operator*= template < typename T > qua& operator*=(qua& xs, T y); template < typename T > vec& operator*=(vec& xs, const qua& ys); template < typename T > qua& operator*=(qua& xs, const qua& ys); // operator/ template < typename T, typename U > auto operator/(const qua& xs, U y); template < typename T, typename U > auto operator/(T x, const qua& ys); // operator/= template < typename T > qua& operator/=(qua& xs, T y); // operator== template < typename T > bool operator==(const qua& xs, const qua& ys); // operator!= template < typename T > bool operator!=(const qua& xs, const qua& ys); // operator< template < typename T > bool operator<(const qua& xs, const qua& ys); ``` ### Common Functions #### Scalar ```cpp template < arithmetic T > T abs(T x); template < arithmetic T > T sqr(T x); template < arithmetic T > T sign(T x); template < floating_point T > T rcp(T x); template < floating_point T > T floor(T x); template < floating_point T > T trunc(T x); template < floating_point T > T round(T x); template < floating_point T > T ceil(T x); template < floating_point T > T fract(T x); template < floating_point T > T fmod(T x, T y); template < floating_point T > T modf(T x, T* y); template < floating_point T > T copysign(T x, T s); template < arithmetic T > T min(T x, T y); template < arithmetic T > T max(T x, T y); template < arithmetic T > T clamp(T x, T min_x, T max_x); template < arithmetic T > T saturate(T x); template < floating_point T > T lerp(T x, T y, T a); template < floating_point T > T lerp(T x, T y, T x_a, T y_a); template < floating_point T > T step(T edge, T x); template < floating_point T > T smoothstep(T edge0, T edge1, T x); ``` #### Vector ```cpp template < typename T, size_t Size > vec abs(const vec& xs); template < typename T, size_t Size > vec sqr(const vec& xs); template < typename T, size_t Size > vec sign(const vec& xs); template < typename T, size_t Size > vec rcp(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 > vec copysign(const vec& xs, T s); template < typename T, size_t Size > vec copysign(const vec& xs, const vec& ss); template < typename T, size_t Size > T min(const vec& xs); template < typename T, size_t Size > vec min(const vec& xs, T y); template < typename T, size_t Size > vec min(T x, const vec& ys); template < typename T, size_t Size > vec min(const vec& xs, const vec& ys); template < typename T, size_t Size > T max(const vec& xs); template < typename T, size_t Size > vec max(const vec& xs, T y); template < typename T, size_t Size > vec max(T x, const vec& ys); template < typename T, size_t Size > vec max(const vec& xs, const vec& ys); template < typename T, size_t Size > vec clamp(const vec& xs, T min_x, T max_x); template < typename T, size_t Size > vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs); template < typename T, size_t Size > vec saturate(const vec& xs); template < typename T, size_t Size > vec lerp(const vec& xs, const vec& ys, T a); template < typename T, size_t Size > vec lerp(const vec& xs, const vec& ys, T x_a, T y_a); template < typename T, size_t Size > vec lerp(const vec& xs, const vec& ys, const vec& as); template < typename T, size_t Size > vec lerp(const vec& xs, const vec& ys, const vec& xs_a, const vec& ys_a); template < typename T, size_t Size > vec step(T edge, const vec& xs); template < typename T, size_t Size > vec step(const vec& edges, const vec& xs); template < typename T, size_t Size > vec smoothstep(T edge0, T edge1, const vec& xs); template < typename T, size_t Size > vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); ``` #### Quaternion ```cpp template < typename T > qua lerp(const qua& xs, const qua& ys, T a); template < typename T > qua lerp(const qua& xs, const qua& ys, T xs_a, T ys_a); template < typename T > qua nlerp(const qua& unit_xs, const qua& unit_ys, T a); template < typename T > qua slerp(const qua& unit_xs, const qua& unit_ys, T a); ``` ### Angle and Trigonometric Functions #### Scalar ```cpp template < floating_point T > T radians(T degrees); template < floating_point T > T degrees(T radians); template < floating_point T > T sin(T x); template < floating_point T > T cos(T x); template < floating_point T > T tan(T x); template < floating_point T > T asin(T x); template < floating_point T > T acos(T x); template < floating_point T > T atan(T x); template < floating_point T > T atan2(T y, T x); template < floating_point T > T sinh(T x); template < floating_point T > T cosh(T x); template < floating_point T > T tanh(T x); template < floating_point T > T asinh(T x); template < floating_point T > T acosh(T x); template < floating_point T > T atanh(T x); template < floating_point T > pair sincos(T x); template < floating_point T > void sincos(T x, T* s, T* c); ``` #### Vector ```cpp template < typename T, size_t Size > vec radians(const vec& degrees); template < typename T, size_t Size > 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 > pair, vec> sincos(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); template < floating_point T > T exp(T x); template < floating_point T > T log(T x); template < floating_point T > T exp2(T x); template < floating_point T > T log2(T x); template < floating_point T > T sqrt(T x); template < floating_point T > T rsqrt(T x); ``` #### 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); ``` ### Geometric Functions #### Scalar ```cpp template < arithmetic T, arithmetic U , arithmetic V = decltype(declval() * declval()) > V dot(T x, U y); template < arithmetic T > T length(T x); template < arithmetic T > T rlength(T x); template < arithmetic T > T length2(T x); template < arithmetic T > T rlength2(T x); template < arithmetic T > T distance(T x, T y); template < arithmetic T > T distance2(T x, T y); template < floating_point T > T normalize(T x); template < floating_point T > T faceforward(T n, T i, T nref); template < floating_point T > T reflect(T i, T n); template < floating_point T > T refract(T i, T n, T eta); ``` #### Vector ```cpp template < typename T, typename U, size_t Size , typename V = decltype(declval() * declval()) > V dot(const vec& xs, const vec& ys); template < typename T, size_t Size > T length(const vec& xs); template < typename T, size_t Size > T rlength(const vec& xs); template < typename T, size_t Size > T length2(const vec& xs); template < typename T, size_t Size > T rlength2(const vec& xs); template < typename T, size_t Size > T distance(const vec& xs, const vec& ys); template < typename T, size_t Size > T distance2(const vec& xs, const vec& ys); template < typename T, typename U , typename V = decltype(declval() * declval()) > V cross(const vec& xs, const vec& ys); template < typename T, typename U , typename V = decltype(declval() * declval()) > 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 > vec faceforward(const vec& n, const vec& i, const vec& nref); template < typename T, size_t Size > vec reflect(const vec& i, const vec& n); template < typename T, size_t Size > vec refract(const vec& i, const vec& n, T eta); ``` #### Quaternion ```cpp template < typename T, typename U , typename V = decltype(dot( declval>(), declval>())) > V dot(const qua& xs, const qua& ys); template < typename T > T length(const qua& xs); template < typename T > T rlength(const qua& xs); template < typename T > T length2(const qua& xs); template < typename T > T rlength2(const qua& xs); template < typename T > T distance(const qua& xs, const qua& ys); template < typename T > qua normalize(const qua& xs); ``` ### Relational Functions #### Scalar ```cpp template < arithmetic T > bool any(T x); template < arithmetic T > bool all(T x); template < arithmetic T > bool approx(T x, T y); template < arithmetic T > bool approx(T x, T y, T epsilon); template < arithmetic T > bool less(T x, T y); template < arithmetic T > bool less_equal(T x, T y); template < arithmetic T > bool greater(T x, T y); template < arithmetic T > bool greater_equal(T x, T y); template < arithmetic T > bool equal_to(T x, T y); template < arithmetic T > bool not_equal_to(T x, T y); ``` #### Vector ```cpp template < typename T, size_t Size , typename U = decltype(any(declval())) > U any(const vec& xs); template < typename T, size_t Size , typename U = decltype(all(declval())) > U all(const vec& xs); template < typename T, size_t Size , typename U = decltype(approx( declval(), declval())) > vec approx(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(approx( declval(), declval(), declval())) > vec approx(const vec& xs, const vec& ys, T epsilon); template < typename T, size_t Size , typename U = decltype(less( declval(), declval())) > vec less(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(less_equal( declval(), declval())) > vec less_equal(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(greater( declval(), declval())) > vec greater(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(greater_equal( declval(), declval())) > vec greater_equal(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(equal_to( declval(), declval())) > vec equal_to(const vec& xs, const vec& ys); template < typename T, size_t Size , typename U = decltype(not_equal_to( declval(), declval())) > vec not_equal_to(const vec& xs, const vec& ys); ``` #### Matrix ```cpp template < typename T, size_t Size , typename U = decltype(any(declval>())) > U any(const mat& xs); template < typename T, size_t Size , typename U = decltype(all(declval>())) > U all(const mat& xs); template < typename T, size_t Size , typename U = typename decltype(approx( declval>(), declval>()))::component_type > mat approx(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(approx( declval>(), declval>(), declval()))::component_type > mat approx(const mat& xs, const mat& ys, T epsilon); template < typename T, size_t Size , typename U = typename decltype(less( declval>(), declval>()))::component_type > mat less(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(less_equal( declval>(), declval>()))::component_type > mat less_equal(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(greater( declval>(), declval>()))::component_type > mat greater(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(greater_equal( declval>(), declval>()))::component_type > mat greater_equal(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(equal_to( declval>(), declval>()))::component_type > mat equal_to(const mat& xs, const mat& ys); template < typename T, size_t Size , typename U = typename decltype(not_equal_to( declval>(), declval>()))::component_type > mat not_equal_to(const mat& xs, const mat& ys); ``` #### Quaternion ```cpp template < typename T , typename U = decltype(any(declval>())) > U any(const qua& xs); template < typename T , typename U = decltype(all(declval>())) > U all(const qua& xs); template < typename T , typename U = typename decltype(approx( declval>(), declval>()))::component_type > vec approx(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(approx( declval>(), declval>(), declval()))::component_type > vec approx(const qua& xs, const qua& ys, T epsilon); template < typename T , typename U = typename decltype(less( declval>(), declval>()))::component_type > vec less(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(less_equal( declval>(), declval>()))::component_type > vec less_equal(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(greater( declval>(), declval>()))::component_type > vec greater(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(greater_equal( declval>(), declval>()))::component_type > vec greater_equal(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(equal_to( declval>(), declval>()))::component_type > vec equal_to(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(not_equal_to( declval>(), declval>()))::component_type > vec not_equal_to(const qua& xs, const qua& ys); ``` ### Matrix Functions ```cpp template < typename T, size_t Size > mat transpose(const mat& m); template < typename T, size_t Size > mat adjugate(const mat& m); template < typename T, size_t Size > T determinant(const mat& m); template < typename T, size_t Size > mat inverse(const mat& m); ``` ### Quaternion Functions ```cpp template < typename T > qua conjugate(const qua& q); template < typename T > qua inverse(const qua& q); ``` ### Units ```cpp template < typename T > inline vec zero2; template < typename T > inline vec zero3; template < typename T > inline vec zero4; template < typename T > inline vec unit2; template < typename T > inline vec unit3; template < typename T > inline vec unit4; template < typename T > inline vec unit2_x; template < typename T > inline vec unit2_y; template < typename T > inline vec unit3_x; template < typename T > inline vec unit3_y; template < typename T > inline vec unit3_z; template < typename T > inline vec unit4_x; template < typename T > inline vec unit4_y; template < typename T > inline vec unit4_z; template < typename T > inline vec unit4_w; template < typename T > inline mat mzero2; template < typename T > inline mat mzero3; template < typename T > inline mat mzero4; template < typename T > inline mat munit2; template < typename T > inline mat munit3; template < typename T > inline mat munit4; template < typename T > inline mat midentity2; template < typename T > inline mat midentity3; template < typename T > inline mat midentity4; template < typename T > inline qua qzero; template < typename T > inline qua qidentity; ``` ### Cast ```cpp template < arithmetic To, arithmetic From > To cast_to(From x); template < typename To, typename From, size_t Size > vec cast_to(const vec& v); template < typename To, typename From, size_t Size > mat cast_to(const mat& m); template < typename To, typename From > qua cast_to(const qua& q); ``` ### Access ```cpp template < typename T, size_t Size > T component(const vec& v, size_t index); template < typename T, size_t Size > vec component(const vec& v, size_t index, T x); template < typename T, size_t Size > vec row(const mat& m, size_t index); template < typename T, size_t Size > mat row(const mat& m, size_t index, const vec& v); template < typename T, size_t Size > vec column(const mat& m, size_t index); template < typename T, size_t Size > mat column(const mat& m, size_t index, const vec& v); template < typename T, size_t Size > vec diagonal(const mat& m); template < typename T, size_t Size > mat diagonal(const mat& m, const vec& diagonal); template < typename T > T real(const qua& q); template < typename T > qua real(qua q, T real); template < typename T > vec imag(const qua& q); template < typename T > qua imag(qua q, const vec& imag); ``` ### Matrix Transform 3D ```cpp template < typename T > mat trs(const vec& t, const mat& r); template < typename T > mat trs(const vec& t, const mat& r, const vec& s); template < typename T > mat trs(const vec& t, const qua& r); template < typename T > mat trs(const vec& t, const qua& r, const vec& s); template < typename T > mat translate(const vec& v); template < typename T > mat rotate(const qua& q); template < typename T > mat rotate4(const qua& q); template < typename T > mat rotate(T angle, const vec& axis); template < typename T > mat rotate4(T angle, const vec& axis); template < typename T > mat rotate_x(T angle); template < typename T > mat rotate4_x(T angle); template < typename T > mat rotate_y(T angle); template < typename T > mat rotate4_y(T angle); template < typename T > mat rotate_z(T angle); template < typename T > mat rotate4_z(T angle); template < typename T > mat scale(const vec& v); template < typename T > mat scale4(const vec& v); template < typename T > mat look_at_lh(const vec& dir, const vec& up); 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& dir, 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 > mat trs(const vec& t, const mat& r); template < typename T > mat trs(const vec& t, const mat& r, const vec& s); template < typename T > mat translate(const vec& v); template < typename T > mat rotate(T angle); template < typename T > mat rotate3(T angle); template < typename T > mat scale(const vec& v); template < typename T > mat scale3(const vec& v); template < typename T > mat shear(const vec& v); template < typename T > mat shear3(const vec& v); ``` ### Matrix Projections ```cpp template < typename T > mat orthographic_lh(T width, T height, T znear, T zfar); template < typename T > mat orthographic_rh(T width, T height, T znear, T zfar); template < typename T > mat orthographic_lh(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat orthographic_rh(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat perspective_lh(T width, T height, T znear, T zfar); template < typename T > mat perspective_rh(T width, T height, T znear, T zfar); template < typename T > mat perspective_lh(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat perspective_rh(T left, T right, T bottom, T top, T znear, T zfar); template < typename T > mat perspective_fov_lh(T fovy, T aspect, T znear, T zfar); template < typename T > mat perspective_fov_rh(T fovy, 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_x(const vec& v, T angle); template < typename T > vec rotate_y(const vec& v, T angle); template < typename T > vec rotate_z(const vec& v, T angle); template < typename T > vec rotate(const vec& v, T angle, const vec& axis); template < typename T, size_t Size > vec project(const vec& v, const vec& normal); template < typename T, size_t Size > vec perpendicular(const vec& v, const vec& normal); ``` ### Quaternion Transform ```cpp template < typename T > qua qrotate(const mat& m); template < typename T > qua qrotate(const qua& q, const mat& m); template < typename T > qua qrotate(const vec& from, const vec& to); template < typename T > qua qrotate(const qua& q, const vec& from, const vec& to); template < typename T > qua qrotate(T angle, const vec& axis); template < typename T > qua qrotate(const qua& q, T angle, const vec& axis); template < typename T > qua qrotate_x(T angle); template < typename T > qua qrotate_x(const qua& q, T angle); template < typename T > qua qrotate_y(T angle); template < typename T > qua qrotate_y(const qua& q, T angle); template < typename T > qua qrotate_z(T angle); template < typename T > qua qrotate_z(const qua& q, T angle); template < typename T > qua qlook_at_lh(const vec& dir, const vec& up); template < typename T > qua qlook_at_rh(const vec& dir, const vec& up); ``` ## [License (MIT)](./LICENSE.md)