27#include <nlohmann/json.hpp>
35 using JSON = nlohmann::json;
113 template <
typename A = T>
typename std::enable_if<std::is_integral<A>::value,
bool>::type
operator==(
Vector2<T> o)
const {
114 return x == o.
x &&
y == o.
y;
116 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
bool>::type
operator==(
Vector2<T> o)
const {
123 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
T>::type
magnitude()
const {
124 return sqrt(
x *
x +
y *
y);
128 return Vector2<T>(std::clamp(
x, minX, maxX), std::clamp(
y, minY, maxY));
135 x = std::clamp(
x, minX, maxX);
136 y = std::clamp(
y, minY, maxY);
143 template <
typename A>
148 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
Vector2<T>>::type
unit()
const {
151 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
float>::type
dist(
Vector2<T> o)
const {
152 return (*
this - o).magnitude();
156 return {
x + o.
y -
y,
y - o.
x +
x};
159 float k =
dot(o) / o.
dot(o);
160 return {k * o.
x, k * o.
y};
175 static Vector2<T> max() {
return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max()}; }
176 static Vector2<T> min() {
return {std::numeric_limits<T>::min(), std::numeric_limits<T>::min()}; }
179 static Vector2<T> random(
T minX,
T maxX,
T minY,
T maxY) {
return {randomRange<T>(minX, maxX), randomRange<T>(minY, maxY)}; }
185 template <
typename T>
271 template <
typename A = T>
typename std::enable_if<std::is_integral<A>::value,
bool>::type
operator==(
Vector3<T> o)
const {
272 return x == o.
x &&
y == o.
y &&
z == o.
z;
274 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
bool>::type
operator==(
Vector3<T> o)
const {
280 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
T>::type
magnitude()
const {
281 return sqrt(
x *
x +
y *
y +
z *
z);
283 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
float>::type
dist(
Vector3<T> o)
const {
284 return (*
this - o).magnitude();
288 return Vector3<T>(std::clamp(
x, minX, maxX), std::clamp(
y, minY, maxY), std::clamp(
z, minZ, maxZ));
295 x = std::clamp(
x, minX, maxX);
296 y = std::clamp(
y, minY, maxY);
297 z = std::clamp(
z, minZ, maxZ);
309 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
Vector3<T>>::type
unit()
const {
332 static Vector3<T> max() {
return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max()}; }
333 static Vector3<T> min() {
return {std::numeric_limits<T>::min(), std::numeric_limits<T>::min(), std::numeric_limits<T>::min()}; }
337 return {randomRange<T>(minX, maxX), randomRange<T>(minY, maxY), randomRange<T>(minZ, maxZ)};
344 template <
typename T>
349 template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
350 Vector4(
float r,
float g,
float b) :
x(r/255.0f),
y(g/255.0f),
z(b/255.0f),
w(1.0f) {}
352 template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
354 x = ((hex >> 16) & 0xFF) / 255.0f;
355 y = ((hex >> 8) & 0xFF) / 255.0f;
356 z = (hex & 0xFF) / 255.0f;
359 template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
361 x = ((hex >> 16) & 0xFF) / 255.0f;
362 y = ((hex >> 8) & 0xFF) / 255.0f;
363 z = (hex & 0xFF) / 255.0f;
461 template <
typename A = T>
typename std::enable_if<std::is_integral<A>::value,
bool>::type
operator==(
Vector4<T> o)
const {
462 return x == o.
x &&
y == o.
y &&
z == o.
z &&
w == o.
w;
464 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
bool>::type
operator==(
Vector4<T> o)
const {
470 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
T>::type
magnitude()
const {
471 return sqrt(
x *
x +
y *
y +
z *
z +
w *
w);
475 return Vector4<T>(std::clamp(
x, minX, maxX), std::clamp(
y, minY, maxY),
476 std::clamp(
z, minZ, maxZ), std::clamp(
w, minW, maxW));
484 x = std::clamp(
x, minX, maxX);
485 y = std::clamp(
y, minY, maxY);
486 z = std::clamp(
z, minZ, maxZ);
487 w = std::clamp(
w, minW, maxW);
497 return Vector4<A>(
static_cast<A>(
x),
static_cast<A>(
y),
static_cast<A>(
z),
static_cast<A>(
w));
500 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
Vector4<T>>::type
unit()
const {
503 template <
typename A = T>
typename std::enable_if<std::is_floating_point<A>::value,
float>::type
dist(
Vector4<T> o)
const {
504 return (*
this - o).magnitude();
573 return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max()};
576 return {std::numeric_limits<T>::min(), std::numeric_limits<T>::min(), std::numeric_limits<T>::min(), std::numeric_limits<T>::min()};
582 return {randomRange<T>(minX, maxX), randomRange<T>(minY, maxY), randomRange<T>(minZ, maxZ), randomRange<T>(minW, maxW)};
636 template <
typename T>
638 os <<
"Vec2(" << vec.
x <<
", " << vec.
y <<
")";
645 template <
typename T>
647 os <<
"Vec3(" << vec.
x <<
", " << vec.
y <<
", " << vec.
z <<
")";
654 template <
typename T>
656 os <<
"Vec4(" << vec.
x <<
", " << vec.
y <<
", " << vec.
z <<
", " << vec.
w <<
")";
663 template <
typename T>
665 p.
x = j[
"x"].get<
T>();
666 p.
y = j[
"y"].get<
T>();
672 template <
typename T>
674 j =
JSON{{
"x", p.
x}, {
"y", p.
y}};
680 template <
typename T>
682 p.
x = j[
"x"].get<
T>();
683 p.
y = j[
"y"].get<
T>();
684 p.
z = j[
"z"].get<
T>();
690 template <
typename T>
692 j =
JSON{{
"x", p.
x}, {
"y", p.
y}, {
"z", p.
z}};
698 template <
typename T>
700 if (j.contains(
"x")) {
701 p.
x = j[
"x"].get<
T>();
702 p.
y = j[
"y"].get<
T>();
703 p.
z = j[
"z"].get<
T>();
704 p.
w = j[
"w"].get<
T>();
707 p.
x = j[
"r"].get<
T>();
708 p.
y = j[
"g"].get<
T>();
709 p.
z = j[
"b"].get<
T>();
710 p.
w = j[
"a"].get<
T>();
717 template <
typename T>
719 j =
JSON{{
"x", p.
x}, {
"y", p.
y}, {
"z", p.
z}, {
"w", p.
w}};
Vector2< T > operator+(Vector2< T > o) const
static Vector2< T > random(T min, T max)
Vector2< T > clamp(Vector2< T > min, Vector2< T > max) const
std::enable_if< std::is_floating_point< A >::value, float >::type dist(Vector2< T > o) const
Vector2< T > operator*(Vector2< T > o) const
static Vector2< T > max()
void operator+=(Vector2< T > o)
Vector2< A > cast() const
Vector2< T > rotateCounterClockwise() const
void clampTo(T minX, T maxX, T minY, T maxY)
Vector2< T > operator/(Vector2< T > o) const
Vector2< T > operator-() const
bool operator<(Vector2< T > o) const
float signedAngle(Vector2< T > to) const
Vector2< T > normalized() const
void clampTo(Vector2< T > min, Vector2< T > max)
static Vector2< T > zero()
Vector2< T > clamp(T minX, T maxX, T minY, T maxY) const
void operator*=(Vector2< T > o)
Vector2< T > operator/(T v) const
T dot(Vector2< T > o) const
std::enable_if< std::is_integral< A >::value, bool >::type operator==(Vector2< T > o) const
static Vector2< T > right()
std::enable_if< std::is_floating_point< A >::value, T >::type magnitude() const
bool operator!=(Vector2< T > o) const
static Vector2< T > min()
friend Vector2< T > operator-(float n, Vector2< T > v)
std::enable_if< std::is_floating_point< A >::value, bool >::type operator==(Vector2< T > o) const
Vector2< T > perpendicular(Vector2< T > o) const
std::enable_if< std::is_floating_point< A >::value, Vector2< T > >::type unit() const
Vector2< T > rotateClockwise() const
Vector2< T > operator-(T v) const
bool operator<=(Vector2< T > o) const
friend Vector2< T > operator/(float n, Vector2< T > v)
friend Vector2< T > operator*(float n, Vector2< T > v)
static Vector2< T > random(T minX, T maxX, T minY, T maxY)
friend Vector2< T > operator+(float n, Vector2< T > v)
Vector2< T > project(Vector2< T > o)
Vector2< T > operator+(T v) const
Vector2< T > operator*(T v) const
static Vector2< T > one()
bool operator>=(Vector2< T > o) const
void operator/=(Vector2< T > o)
bool operator>(Vector2< T > o) const
void operator-=(Vector2< T > o)
T cross(Vector2< T > o) const
Vector2< T > operator-(Vector2< T > o) const
static Vector3< T > right()
Vector3< T > operator-(T v) const
T dot(Vector3< T > o) const
Vector3< T > operator+(T v) const
std::enable_if< std::is_floating_point< A >::value, bool >::type operator==(Vector3< T > o) const
static Vector3< T > max()
void clampTo(T minX, T maxX, T minY, T maxY, T minZ, T maxZ)
Vector3< T > operator-(Vector3< T > o) const
static Vector3< T > zero()
Vector3< T > operator/(T v) const
Vector3< A > cast() const
static Vector3< T > front()
friend Vector3< T > operator-(float n, Vector3< T > v)
std::enable_if< std::is_integral< A >::value, bool >::type operator==(Vector3< T > o) const
bool operator>=(Vector3< T > o) const
void operator+=(Vector3< T > o)
static Vector3< T > random(T min, T max)
bool operator<(Vector3< T > o) const
friend Vector3< T > operator+(float n, Vector3< T > v)
Vector3< T > operator*(T v) const
void operator*=(Vector3< T > o)
void operator/=(Vector3< T > o)
Vector3(T x, Vector2< T > v)
static Vector3< T > one()
Vector3< T > operator+(Vector3< T > o) const
friend Vector3< T > operator/(float n, Vector3< T > v)
Vector3< T > operator*(Vector3< T > o) const
Vector3(Vector2< T > v, T z)
Vector3< T > operator/(Vector3< T > o) const
static Vector3< T > random(T minX, T maxX, T minY, T maxY, T minZ, T maxZ)
void clampTo(Vector3< T > min, Vector3< T > max)
bool operator>(Vector3< T > o) const
std::enable_if< std::is_floating_point< A >::value, Vector3< T > >::type unit() const
void operator-=(Vector3< T > o)
static Vector3< T > min()
std::enable_if< std::is_floating_point< A >::value, T >::type magnitude() const
Vector3< T > clamp(T minX, T maxX, T minY, T maxY, T minZ, T maxZ) const
Vector3< T > operator-() const
std::enable_if< std::is_floating_point< A >::value, float >::type dist(Vector3< T > o) const
bool operator!=(Vector3< T > o) const
bool operator<=(Vector3< T > o) const
friend Vector3< T > operator*(float n, Vector3< T > v)
Vector3< T > clamp(Vector3< T > min, Vector3< T > max) const
bool operator>(Vector4< T > o) const
Vector4< T > operator-(Vector4< T > o) const
void operator*=(Vector4< T > o)
Vector4< T > zwxy() const
Vector4< T > ywzx() const
friend Vector4< T > operator-(float n, Vector4< T > v)
Vector4< T > operator-() const
Vector4(T x, T y, T z, T w)
Vector4(float r, float g, float b)
friend Vector4< T > operator+(float n, Vector4< T > v)
bool operator!=(Vector4< T > o) const
Vector4< T > wyxz() const
static Vector4< T > min()
Vector4< T > wzyx() const
Vector4< T > xwzy() const
Vector4< T > yxzw() const
void operator-=(Vector4< T > o)
std::enable_if< std::is_floating_point< A >::value, float >::type dist(Vector4< T > o) const
Vector4< T > zxyw() const
bool operator<(Vector4< T > o) const
friend Vector4< T > operator/(float n, Vector4< T > v)
T dot(Vector4< T > o) const
Vector4< T > clamp(Vector4< T > min, Vector4< T > max) const
static Vector4< T > zero()
Vector4< T > operator-(T v) const
Vector4< T > zyxw() const
Vector4< A > cast() const
Vector4< T > xywz() const
bool operator<=(Vector4< T > o) const
Vector4< T > yxwz() const
Vector4(T x, Vector2< T > v, T w)
void clampTo(Vector4< T > min, Vector4< T > max)
Vector4< T > xzwy() const
Vector4< T > xyzw() const
Vector4< T > yzxw() const
std::enable_if< std::is_integral< A >::value, bool >::type operator==(Vector4< T > o) const
Vector4< T > operator*(Vector4< T > o) const
void operator+=(Vector4< T > o)
bool operator>=(Vector4< T > o) const
Vector4(Vector3< T > v, T w)
Vector4< T > operator/(T v) const
Vector4< T > zywx() const
Vector4< T > yzwx() const
std::enable_if< std::is_floating_point< A >::value, bool >::type operator==(Vector4< T > o) const
static Vector4< T > random(T min, T max)
Vector4< T > clamp(T minX, T maxX, T minY, T maxY, T minZ, T maxZ, T minW, T maxW) const
Vector4< T > operator+(Vector4< T > o) const
Vector4< T > wxzy() const
Vector4(T x, T y, Vector2< T > v)
Vector4(Vector2< T > v, T z, T w)
Vector4< T > zxwy() const
Vector4< T > zwyx() const
void operator/=(Vector4< T > o)
Vector4< T > ywxz() const
Vector4< T > xzyw() const
static Vector4< T > max()
Vector4< T > wzxy() const
Vector4< T > operator*(T v) const
Vector4< T > operator/(Vector4< T > o) const
friend Vector4< T > operator*(float n, Vector4< T > v)
Vector4< T > operator+(T v) const
Vector4(int hex, float alpha)
static Vector4< T > random(T minX, T maxX, T minY, T maxY, T minZ, T maxZ, T minW, T maxW)
void clampTo(T minX, T maxX, T minY, T maxY, T minZ, T maxZ, T minW, T maxW)
std::enable_if< std::is_floating_point< A >::value, Vector4< T > >::type unit() const
Vector4< T > xwyz() const
std::enable_if< std::is_floating_point< A >::value, T >::type magnitude() const
static Vector4< T > one()
Vector4< T > wyzx() const
Vector4< T > wxyz() const
Vector4(T x, Vector3< T > v)
Vector2< double > Vector2d
Vector3< uint32_t > Vector3ui32
Vector4< unsigned long > Vector4ul
Vector4< unsigned long long > Vector4ull
Vector2< unsigned short > Vector2us
Vector3< long long > Vector3ll
Vector4< unsigned int > Vector4ui
Vector3< unsigned long > Vector3ul
Vector2< long long > Vector2ll
Vector3< short > Vector3s
Vector2< unsigned long long > Vector2ull
Vector4< float > Vector4f
Vector3< size_t > Vector3st
void to_json(JSON &j, const Matrix< w, h, T > &p)
bool isFloatingEqual(T num1, T num2, T epsilon=std::numeric_limits< T >::epsilon())
Vector4< double > Vector4d
Vector3< unsigned int > Vector3ui
Vector2< unsigned int > Vector2ui
Vector2< unsigned char > Vector2uc
Vector2< size_t > Vector2st
Vector3< float > Vector3f
Vector2< short > Vector2s
Vector4< uint32_t > Vector4ui32
Vector2< uint32_t > Vector2ui32
Vector4< long long > Vector4ll
Vector3< double > Vector3d
void from_json(const JSON &j, Matrix< w, h, T > &p)
Vector3< unsigned short > Vector3us
Vector2< unsigned long > Vector2ul
Vector3< unsigned char > Vector3uc
Vector4< unsigned short > Vector4us
Vector4< size_t > Vector4st
std::ostream & operator<<(std::ostream &os, const Kale::Matrix< w, h, T > &mat)
Vector3< unsigned long long > Vector3ull
Vector4< unsigned char > Vector4uc
Vector2< float > Vector2f
Vector4< short > Vector4s