LCOV - code coverage report
Current view: top level - ezlibs - ezVec2.hpp (source / functions) Coverage Total Hit
Test: Coverage (llvm-cov → lcov → genhtml) Lines: 90.4 % 115 104
Test Date: 2025-09-16 22:55:37 Functions: 97.6 % 168 164
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81.6 % 76 62

             Branch data     Line data    Source code
       1                 :             : #pragma once
       2                 :             : 
       3                 :             : #ifndef EZ_TOOLS_VEC2
       4                 :             : #define EZ_TOOLS_VEC2
       5                 :             : #endif  // EZ_TOOLS_VEC2
       6                 :             : 
       7                 :             : /*
       8                 :             : MIT License
       9                 :             : 
      10                 :             : Copyright (c) 2014-2024 Stephane Cuillerdier (aka aiekick)
      11                 :             : 
      12                 :             : Permission is hereby granted, free of charge, to any person obtaining a copy
      13                 :             : of this software and associated documentation files (the "Software"), to deal
      14                 :             : in the Software without restriction, including without limitation the rights
      15                 :             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      16                 :             : copies of the Software, and to permit persons to whom the Software is
      17                 :             : furnished to do so, subject to the following conditions:
      18                 :             : 
      19                 :             : The above copyright notice and this permission notice shall be included in all
      20                 :             : copies or substantial portions of the Software.
      21                 :             : 
      22                 :             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      23                 :             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      25                 :             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      27                 :             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      28                 :             : SOFTWARE.
      29                 :             : */
      30                 :             : 
      31                 :             : // ezVec2 is part of the ezLibs project : https://github.com/aiekick/ezLibs.git
      32                 :             : 
      33                 :             : #include <cmath>
      34                 :             : #include <type_traits>
      35                 :             : #include <string>
      36                 :             : #include <vector>
      37                 :             : 
      38                 :             : #ifdef min
      39                 :             : #undef min
      40                 :             : #endif  // min
      41                 :             : 
      42                 :             : #ifdef max
      43                 :             : #undef max
      44                 :             : #endif  // max
      45                 :             : 
      46                 :             : // Namespace ez
      47                 :             : namespace ez {
      48                 :             : 
      49                 :             : // Disable specific types for template functions
      50                 :             : template <typename T>
      51                 :             : struct is_valid_type : std::integral_constant<bool, (std::is_floating_point<T>::value || (std::is_integral<T>::value && sizeof(T) > 1))> {};
      52                 :             : 
      53                 :             : // Vector 2D template class
      54                 :             : template <typename T>
      55                 :             : struct vec2 {
      56                 :             :     // Disable this template if T is not an integral or floating point type
      57                 :             :     //static_assert(is_valid_type<T>::value, "Invalid type for vec2. Only integral types larger than (u)int8_t and floating-point types are allowed.");
      58                 :             : 
      59                 :             :     T x = static_cast<T>(0), y = static_cast<T>(0);
      60                 :             : 
      61                 :             :     // Constructors
      62                 :           9 :     vec2() = default;
      63                 :             : 
      64                 :             :     // Constructor with type conversion
      65                 :             :     template <typename U>
      66                 :             :     vec2(const vec2<U>& a) : x(static_cast<T>(a.x)), y(static_cast<T>(a.y)) {}
      67                 :             : 
      68                 :             :     // Constructor with type conversion
      69                 :             :     template <typename U>
      70                 :             :     vec2(const U& a) : x(static_cast<T>(a.x)), y(static_cast<T>(a.y)) {}
      71                 :             : 
      72                 :             :     vec2(T a) : x(a), y(a) {}
      73                 :             : 
      74                 :         809 :     vec2(T a, T b) : x(a), y(b) {}
      75                 :             : 
      76                 :             : #ifdef EZ_STR
      77                 :             :     vec2(const std::vector<std::string>& vArray) {
      78                 :             :         const size_t s = vArray.size();
      79                 :             :         if (s > 0) {
      80                 :             :             str::stringToNumber(vArray.at(0), x);
      81                 :             :         }
      82                 :             :         if (s > 1) {
      83                 :             :             str::stringToNumber(vArray.at(1), y);
      84                 :             :         }
      85                 :             :     };
      86                 :             : 
      87                 :             :     vec2(const std::string& vec, char c = ';', const vec2<T>* def = nullptr) {
      88                 :             :         if (def) {
      89                 :             :             x = def->x;
      90                 :             :             y = def->y;
      91                 :             :         }
      92                 :             :         std::vector<T> result = str::stringToNumberVector<T>(vec, c);
      93                 :             :         const size_t s = result.size();
      94                 :             :         if (s > 0) {
      95                 :             :             x = result.at(0);
      96                 :             :         }
      97                 :             :         if (s > 1) {
      98                 :             :             x = result.at(1);
      99                 :             :         }
     100                 :             :     }
     101                 :             : #endif
     102                 :             : 
     103                 :             :     // Element access operator
     104                 :             :     T& operator[](size_t i) { return (&x)[i]; }
     105                 :             : 
     106                 :             :     // Offset function
     107                 :           6 :     vec2 Offset(T vX, T vY) const { return vec2(x + vX, y + vY); }
     108                 :             : 
     109                 :             :     // Set function
     110                 :             :     void Set(T vX, T vY) {
     111                 :             :         x = vX;
     112                 :             :         y = vY;
     113                 :             :     }
     114                 :             : 
     115                 :             :     vec2 lerp(const vec2<T>& vPos, T vLerpValue) {
     116                 :             :         static_assert(std::is_floating_point<T>::value, "lerp is only valid for floating point types");
     117                 :             :         return vec2(  //
     118                 :             :             ez::lerp(x, vPos.x, vLerpValue),
     119                 :             :             ez::lerp(y, vPos.y, vLerpValue));
     120                 :             : 
     121                 :             :     }
     122                 :             : 
     123                 :             :     vec2 lerp(const vec2<T>& vPos, const vec2<T>& vLerpValue) {
     124                 :             :         static_assert(std::is_floating_point<T>::value, "lerp is only valid for floating point types");
     125                 :             :         return vec2(  //
     126                 :             :             ez::lerp(x, vPos.x, vLerpValue.x),
     127                 :             :             ez::lerp(y, vPos.y, vLerpValue.y));
     128                 :             :     }
     129                 :             : 
     130                 :             :     // Negation operator
     131                 :           4 :     vec2 operator-() const {
     132                 :           4 :         static_assert(std::is_signed<T>::value, "Negation operator is only valid for signed types");
     133                 :           4 :         return vec2(-x, -y);
     134                 :           4 :     }
     135                 :             : 
     136                 :             :     // Logical NOT operator
     137                 :             :     vec2 operator!() const {
     138                 :             :         static_assert(std::is_integral<T>::value, "Logical NOT is only valid for integral types");
     139                 :             :         return vec2(!x, !y);
     140                 :             :     }
     141                 :             : 
     142                 :             :     // Increment and decrement operators
     143                 :             :     vec2& operator++() {
     144                 :             :         ++x;
     145                 :             :         ++y;
     146                 :             :         return *this;
     147                 :             :     }
     148                 :             : 
     149                 :             :     vec2& operator--() {
     150                 :             :         --x;
     151                 :             :         --y;
     152                 :             :         return *this;
     153                 :             :     }
     154                 :             : 
     155                 :             :     vec2 operator++(int) {
     156                 :             :         vec2 tmp = *this;
     157                 :             :         ++*this;
     158                 :             :         return tmp;
     159                 :             :     }
     160                 :             : 
     161                 :             :     vec2 operator--(int) {
     162                 :             :         vec2 tmp = *this;
     163                 :             :         --*this;
     164                 :             :         return tmp;
     165                 :             :     }
     166                 :             : 
     167                 :             :     // Compound assignment operators
     168                 :             :     void operator+=(T a) {
     169                 :             :         x += a;
     170                 :             :         y += a;
     171                 :             :     }
     172                 :             : 
     173                 :             :     void operator+=(const vec2<T>& v) {
     174                 :             :         x += v.x;
     175                 :             :         y += v.y;
     176                 :             :     }
     177                 :             : 
     178                 :             :     void operator-=(T a) {
     179                 :             :         x -= a;
     180                 :             :         y -= a;
     181                 :             :     }
     182                 :             : 
     183                 :             :     void operator-=(const vec2<T>& v) {
     184                 :             :         x -= v.x;
     185                 :             :         y -= v.y;
     186                 :             :     }
     187                 :             : 
     188                 :             :     void operator*=(T a) {
     189                 :             :         x *= a;
     190                 :             :         y *= a;
     191                 :             :     }
     192                 :             : 
     193                 :           0 :     void operator*=(const vec2<T>& v) {
     194                 :           0 :         x *= v.x;
     195                 :           0 :         y *= v.y;
     196                 :           0 :     }
     197                 :             : 
     198                 :             :     void operator/=(T a) {
     199                 :             :         x /= a;
     200                 :             :         y /= a;
     201                 :             :     }
     202                 :             : 
     203                 :             :     void operator/=(const vec2<T>& v) {
     204                 :             :         x /= v.x;
     205                 :             :         y /= v.y;
     206                 :             :     }
     207                 :             : 
     208                 :             :     // Comparison operators
     209                 :             :     bool operator==(T a) const { return (x == a) && (y == a); }
     210                 :             : 
     211                 :             :     bool operator==(const vec2<T>& v) const { return (x == v.x) && (y == v.y); }
     212                 :             : 
     213                 :             :     bool operator!=(T a) const { return (x != a) || (y != a); }
     214                 :             : 
     215                 :             :     bool operator!=(const vec2<T>& v) const { return (x != v.x) || (y != v.y); }
     216                 :             : 
     217                 :             :     // Length and normalization
     218                 :          10 :     T lengthSquared() const { return x * x + y * y; }
     219                 :             : 
     220                 :          10 :     T length() const { return static_cast<T>(ez::sqrt(lengthSquared())); }
     221                 :             : 
     222                 :           4 :     T normalize() {
     223                 :           4 :         T len = length();
     224 [ -  + ][ -  + ]:           4 :         if (len < static_cast<T>(1e-5))
     225                 :           0 :             return static_cast<T>(0.0);
     226                 :           4 :         T invLen = static_cast<T>(1.0) / len;
     227                 :           4 :         x *= invLen;
     228                 :           4 :         y *= invLen;
     229                 :           4 :         return len;
     230                 :           4 :     }
     231                 :             : 
     232                 :           2 :     vec2 GetNormalized() const {
     233                 :           2 :         vec2 n(x, y);
     234                 :           2 :         n.normalize();
     235                 :           2 :         return n;
     236                 :           2 :     }
     237                 :             : 
     238                 :             :     // Sum functions
     239                 :           6 :     T sum() const { return x + y; }
     240                 :             : 
     241                 :             :     T sumAbs() const { return ez::abs(x) + ez::abs(y); }
     242                 :             : 
     243                 :             :     // Empty checks
     244 [ +  + ][ +  + ]:          24 :     bool emptyAND() const { return x == static_cast<T>(0) && y == static_cast<T>(0); }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     245                 :             : 
     246 [ +  + ][ +  + ]:          24 :     bool emptyOR() const { return x == static_cast<T>(0) || y == static_cast<T>(0); }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     247                 :             : 
     248                 :             : #ifdef EZ_STR
     249                 :             :     // Convert to string
     250                 :             :     std::string string(char c = ';') const { return str::toStr(x) + c + str::toStr(y); }
     251                 :             :     std::vector<std::string> array(char c = ';') const { return {str::toStr(x), str::toStr(y)}; }
     252                 :             : #endif
     253                 :             : 
     254                 :             :     // Ratio functions
     255                 :             :     template <typename U>
     256                 :             :     U ratioXY() const {
     257                 :             :         if (y != static_cast<T>(0))
     258                 :             :             return static_cast<U>(x) / static_cast<U>(y);
     259                 :             :         return static_cast<U>(0);
     260                 :             :     }
     261                 :             : 
     262                 :             :     template <typename U>
     263                 :             :     U ratioYX() const {
     264                 :             :         if (x != static_cast<T>(0))
     265                 :             :             return static_cast<U>(y) / static_cast<U>(x);
     266                 :             :         return static_cast<U>(0);
     267                 :             :     }
     268                 :             : 
     269                 :             :     // Min and max
     270 [ +  - ][ +  - ]:           6 :     T min() const { return x < y ? x : y; }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     271                 :             : 
     272 [ -  + ][ -  + ]:           6 :     T max() const { return x > y ? x : y; }
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     273                 :             : };
     274                 :             : 
     275                 :             : // Operators
     276                 :             : template <typename T>
     277                 :           6 : inline vec2<T> operator+(const vec2<T>& v, T f) {
     278                 :           6 :     return vec2<T>(v.x + f, v.y + f);
     279                 :           6 : }
     280                 :             : 
     281                 :             : template <typename T>
     282                 :           6 : inline vec2<T> operator+(T f, const vec2<T>& v) {
     283                 :           6 :     return vec2<T>(v.x + f, v.y + f);
     284                 :           6 : }
     285                 :             : 
     286                 :             : template <typename T>
     287                 :           6 : inline vec2<T> operator+(const vec2<T>& v, const vec2<T>& f) {
     288                 :           6 :     return vec2<T>(v.x + f.x, v.y + f.y);
     289                 :           6 : }
     290                 :             : 
     291                 :             : template <typename T>
     292                 :           6 : inline vec2<T> operator-(const vec2<T>& v, T f) {
     293                 :           6 :     return vec2<T>(v.x - f, v.y - f);
     294                 :           6 : }
     295                 :             : 
     296                 :             : template <typename T>
     297                 :           6 : inline vec2<T> operator-(T f, const vec2<T>& v) {
     298                 :           6 :     return vec2<T>(f - v.x, f - v.y);
     299                 :           6 : }
     300                 :             : 
     301                 :             : template <typename T>
     302                 :           8 : inline vec2<T> operator-(const vec2<T>& v, const vec2<T>& f) {
     303                 :           8 :     return vec2<T>(v.x - f.x, v.y - f.y);
     304                 :           8 : }
     305                 :             : 
     306                 :             : template <typename T>
     307                 :           6 : inline vec2<T> operator*(const vec2<T>& v, T f) {
     308                 :           6 :     return vec2<T>(v.x * f, v.y * f);
     309                 :           6 : }
     310                 :             : 
     311                 :             : template <typename T>
     312                 :           8 : inline vec2<T> operator*(T f, const vec2<T>& v) {
     313                 :           8 :     return vec2<T>(v.x * f, v.y * f);
     314                 :           8 : }
     315                 :             : 
     316                 :             : template <typename T>
     317                 :           6 : inline vec2<T> operator*(const vec2<T>& v, const vec2<T>& f) {
     318                 :           6 :     return vec2<T>(v.x * f.x, v.y * f.y);
     319                 :           6 : }
     320                 :             : 
     321                 :             : template <typename T>
     322                 :           4 : inline vec2<T> operator/(const vec2<T>& v, T f) {
     323                 :           4 :     return vec2<T>(v.x / f, v.y / f);
     324                 :           4 : }
     325                 :             : 
     326                 :             : template <typename T>
     327                 :           2 : inline vec2<T> operator/(T f, const vec2<T>& v) {
     328                 :           2 :     return vec2<T>(f / v.x, f / v.y);
     329                 :           2 : }
     330                 :             : 
     331                 :             : template <typename T>
     332                 :           4 : inline vec2<T> operator/(const vec2<T>& v, const vec2<T>& f) {
     333                 :           4 :     return vec2<T>(v.x / f.x, v.y / f.y);
     334                 :           4 : }
     335                 :             : 
     336                 :             : // Comparison operators
     337                 :             : template <typename T>
     338                 :             : inline bool operator<(const vec2<T>& v, const vec2<T>& f) {
     339                 :             :     return v.x < f.x && v.y < f.y;
     340                 :             : }
     341                 :             : 
     342                 :             : template <typename T>
     343                 :             : inline bool operator<(const vec2<T>& v, T f) {
     344                 :             :     return v.x < f && v.y < f;
     345                 :             : }
     346                 :             : 
     347                 :             : template <typename T>
     348                 :             : inline bool operator>(const vec2<T>& v, const vec2<T>& f) {
     349                 :             :     return v.x > f.x && v.y > f.y;
     350                 :             : }
     351                 :             : 
     352                 :             : template <typename T>
     353                 :             : inline bool operator>(const vec2<T>& v, T f) {
     354                 :             :     return v.x > f && v.y > f;
     355                 :             : }
     356                 :             : 
     357                 :             : template <typename T>
     358                 :             : inline bool operator<=(const vec2<T>& v, const vec2<T>& f) {
     359                 :             :     return v.x <= f.x && v.y <= f.y;
     360                 :             : }
     361                 :             : 
     362                 :             : template <typename T>
     363                 :             : inline bool operator<=(const vec2<T>& v, T f) {
     364                 :             :     return v.x <= f && v.y <= f;
     365                 :             : }
     366                 :             : 
     367                 :             : template <typename T>
     368                 :             : inline bool operator>=(const vec2<T>& v, const vec2<T>& f) {
     369                 :             :     return v.x >= f.x && v.y >= f.y;
     370                 :             : }
     371                 :             : 
     372                 :             : template <typename T>
     373                 :             : inline bool operator>=(const vec2<T>& v, T f) {
     374                 :             :     return v.x >= f && v.y >= f;
     375                 :             : }
     376                 :             : 
     377                 :             : template <typename T>
     378                 :             : inline bool operator!=(const vec2<T>& v, const vec2<T>& f) {
     379                 :             :     return f.x != v.x || f.y != v.y;
     380                 :             : }
     381                 :             : 
     382                 :             : template <typename T>
     383                 :             : inline bool operator==(const vec2<T>& v, const vec2<T>& f) {
     384                 :             :     return f.x == v.x && f.y == v.y;
     385                 :             : }
     386                 :             : 
     387                 :             : // Additional vector operations
     388                 :             : template <typename T>
     389                 :           2 : inline vec2<T> floor(const vec2<T>& a) {
     390                 :           2 :     return vec2<T>(ez::floor(a.x), ez::floor(a.y));
     391                 :           2 : }
     392                 :             : 
     393                 :             : template <typename T>
     394                 :           2 : inline vec2<T> fract(const vec2<T>& a) {
     395                 :           2 :     static_assert(std::is_floating_point<T>::value, "fract is only valid for theses types : float, double, long double");
     396                 :           2 :     return vec2<T>(fract(a.x), fract(a.y));
     397                 :           2 : }
     398                 :             : 
     399                 :             : template <typename T>
     400                 :           2 : inline vec2<T> ceil(const vec2<T>& a) {
     401                 :           2 :     return vec2<T>(ez::ceil(a.x), ez::ceil(a.y));
     402                 :           2 : }
     403                 :             : 
     404                 :             : template <typename T>
     405                 :           6 : inline vec2<T> mini(const vec2<T>& a, const vec2<T>& b) {
     406                 :           6 :     return vec2<T>(ez::mini(a.x, b.x), ez::mini(a.y, b.y));
     407                 :           6 : }
     408                 :             : 
     409                 :             : template <typename T>
     410                 :           6 : inline vec2<T> maxi(const vec2<T>& a, const vec2<T>& b) {
     411                 :           6 :     return vec2<T>(ez::maxi(a.x, b.x), ez::maxi(a.y, b.y));
     412                 :           6 : }
     413                 :             : 
     414                 :             : // scalar prodcut not possible with (u)int8
     415                 :             : template <typename T>
     416                 :           8 : inline T dot(const vec2<T>& a, const vec2<T>& b) {
     417                 :           8 :     return a.x * b.x + a.y * b.y;
     418                 :           8 : }
     419                 :             : 
     420                 :             : template <typename T>
     421                 :           6 : inline T det(const vec2<T>& a, const vec2<T>& b) {
     422                 :           6 :     return a.x * b.y - a.y * b.x;
     423                 :           6 : }
     424                 :             : 
     425                 :             : template <typename T>
     426                 :             : inline T length(const vec2<T>& v) {
     427                 :             :     return sqrt(dot(v,v));
     428                 :             : }
     429                 :             : 
     430                 :             : template <typename T>
     431                 :             : inline vec2<T> cross(const vec2<T>& a, const vec2<T>& b) {
     432                 :             :     return vec2<T>(a.x * b.y - a.y * b.x, a.y * b.x - a.x * b.y);
     433                 :             : }
     434                 :             : 
     435                 :             : template <typename T>
     436                 :           2 : inline vec2<T> reflect(const vec2<T>& I, const vec2<T>& N) {
     437                 :           2 :     static_assert(std::is_floating_point<T>::value, "fract is only valid for floating point types");
     438                 :           2 :     return I - static_cast<T>(2) * ez::dot(N, I) * N;
     439                 :           2 : }
     440                 :             : 
     441                 :             : template <typename T>
     442                 :           8 : inline vec2<T> sign(const vec2<T>& a) {
     443                 :           8 :     return vec2<T>(ez::sign(a.x), ez::sign(a.y));
     444                 :           8 : }
     445                 :             : 
     446                 :             : template <typename T>
     447                 :           2 : inline vec2<T> sin(const vec2<T>& a) {
     448                 :           2 :     return vec2<T>(ez::sin(a.x), ez::sin(a.y));
     449                 :           2 : }
     450                 :             : 
     451                 :             : template <typename T>
     452                 :           2 : inline vec2<T> cos(const vec2<T>& a) {
     453                 :           2 :     return vec2<T>(ez::cos(a.x), ez::cos(a.y));
     454                 :           2 : }
     455                 :             : 
     456                 :             : template <typename T>
     457                 :           2 : inline vec2<T> tan(const vec2<T>& a) {
     458                 :           2 :     return vec2<T>(ez::tan(a.x), ez::tan(a.y));
     459                 :           2 : }
     460                 :             : 
     461                 :             : template <typename T>
     462                 :           2 : inline vec2<T> atan(const vec2<T>& a) {
     463                 :           2 :     return vec2<T>(ez::atan(a.x), ez::atan(a.y));
     464                 :           2 : }
     465                 :             : 
     466                 :             : // Clamps a value between 0 and 1.
     467                 :             : // Works with both integral and floating-point types.
     468                 :             : template <typename T>
     469                 :             : inline vec2<T> clamp(vec2<T> n) {
     470                 :             :     vec2<T> ret;
     471                 :             :     ret.x = ez::clamp(n.x);
     472                 :             :     ret.y = ez::clamp(n.y);
     473                 :             :     return ret;
     474                 :             : }
     475                 :             : 
     476                 :             : // Clamps a value between 0 and b.
     477                 :             : // Works with both integral and floating-point types.
     478                 :             : template <typename T>
     479                 :             : inline vec2<T> clamp(vec2<T> n, T b) {
     480                 :             :     vec2<T> ret;
     481                 :             :     ret.x = ez::clamp(n.x);
     482                 :             :     ret.y = ez::clamp(n.y);
     483                 :             :     return ret;
     484                 :             : }
     485                 :             : 
     486                 :             : // Clamps a value between a and b.
     487                 :             : // Works with both integral and floating-point types.
     488                 :             : template <typename T>
     489                 :             : inline vec2<T> clamp(vec2<T> n, T a, T b) {
     490                 :             :     vec2<T> ret;
     491                 :             :     ret.x = ez::clamp(n.x, a, b);
     492                 :             :     ret.y = ez::clamp(n.y, a, b);
     493                 :             :     return ret;
     494                 :             : }
     495                 :             : 
     496                 :             : // Using statements for different types of vec2
     497                 :             : using dvec2 = vec2<double>;
     498                 :             : using fvec2 = vec2<float>;
     499                 :             : using f32vec2 = vec2<float>;
     500                 :             : using f64vec2 = vec2<double>;
     501                 :             : using i8vec2 = vec2<int8_t>;
     502                 :             : using i16vec2 = vec2<int16_t>;
     503                 :             : using ivec2 = vec2<int32_t>;
     504                 :             : using i32vec2 = vec2<int32_t>;
     505                 :             : using i64vec2 = vec2<int64_t>;
     506                 :             : using u8vec2 = vec2<uint8_t>;
     507                 :             : using u16vec2 = vec2<uint16_t>;
     508                 :             : using uvec2 = vec2<uint32_t>;
     509                 :             : using u32vec2 = vec2<uint32_t>;
     510                 :             : using u64vec2 = vec2<uint64_t>;
     511                 :             : 
     512                 :             : // Conversion functions
     513                 :           0 : inline fvec2 convert(const ivec2& v) {
     514                 :           0 :     return fvec2(static_cast<float>(v.x), static_cast<float>(v.y));
     515                 :           0 : }
     516                 :             : 
     517                 :           0 : inline ivec2 convert(const fvec2& v) {
     518                 :           0 :     return ivec2(static_cast<int>(v.x), static_cast<int>(v.y));
     519                 :           0 : }
     520                 :             : 
     521                 :             : #ifdef floatIsValid
     522                 :             : // Float validation
     523                 :             : inline bool valid(const fvec2& a) {
     524                 :             :     return floatIsValid(a.x) && floatIsValid(a.y);
     525                 :             : }
     526                 :             : #endif
     527                 :             : 
     528                 :             : #ifdef isEqual
     529                 :             : // Float comparison operators
     530                 :             : inline bool operator==(const fvec2& v, const fvec2& f) {
     531                 :             :     return isEqual(f.x, v.x) && isEqual(f.y, v.y);
     532                 :             : }
     533                 :             : #endif
     534                 :             : 
     535                 :             : #ifdef isDifferent
     536                 :             : inline bool operator!=(const fvec2& v, const fvec2& f) {
     537                 :             :     return isDifferent(f.x, v.x) || isDifferent(f.y, v.y);
     538                 :             : }
     539                 :             : #endif
     540                 :             : 
     541                 :             : // Function to compute the angle in radians from a vec2, only for floating-point types
     542                 :             : // Allowed types: float, double, long double
     543                 :             : template <typename T>
     544                 :             : inline typename std::enable_if<std::is_floating_point<T>::value, T>::type radAngleFromVec2(const vec2<T>& vec) {
     545                 :             :     T angle = static_cast<T>(0);
     546                 :             :     if (vec.lengthSquared() > static_cast<T>(0) && vec.x != static_cast<T>(0)) {
     547                 :             :         angle = ez::atan(vec.y / vec.x);
     548                 :             :     }
     549                 :             :     return angle;
     550                 :             : }
     551                 :             : 
     552                 :             : // Function to compute the continuous angle in radians from a vec2 with an offset, only for floating-point types
     553                 :             : // Allowed types: float, double, long double
     554                 :             : template <typename T>
     555                 :             : inline typename std::enable_if<std::is_floating_point<T>::value, T>::type radAngleContinuousFromVec2(const vec2<T>& vec, T angleOffset) {
     556                 :             :     T angle = static_cast<T>(0);
     557                 :             :     if (vec.x > static_cast<T>(0)) {
     558                 :             :         angle = ez::atan(vec.y / vec.x);
     559                 :             :     } else if (vec.x < static_cast<T>(0)) {
     560                 :             :         angle = static_cast<T>(M_PI) - ez::atan(-vec.y / vec.x);
     561                 :             :     }
     562                 :             :     return angle - angleOffset;
     563                 :             : }
     564                 :             : 
     565                 :             : template <typename T>
     566                 :             : inline std::istream& operator>>(std::istream& vIn, vec2<T>& vType) {
     567                 :             :     char separator;
     568                 :             :     if (vIn >> vType.x >> separator >> vType.y) {
     569                 :             :         if (separator != ';') {
     570                 :             :             vIn.setstate(std::ios::failbit);
     571                 :             :         }
     572                 :             :     }
     573                 :             :     return vIn;
     574                 :             : }
     575                 :             : 
     576                 :             : template <typename T>
     577                 :             : inline std::ostream& operator<<(std::ostream& vOut, const vec2<T>& vType) {
     578                 :             :     vOut << vType.x << ";" << vType.y;
     579                 :             :     return vOut;
     580                 :             : }
     581                 :             : 
     582                 :             : }  // namespace ez
        

Generated by: LCOV version 2.0-1