12 #include <type_traits>
20 template<
bool c,
class T1,
class T2>
struct static_if {
24 template<
class T1,
class T2>
struct static_if<false, T1, T2> {
30 template<
class T,
size_t d,
bool ref = false>
class Vec
42 static_assert(!ref,
"Cannot be used with vector references");
44 for (
size_t k = 0; k < d; k++)
45 ret[k] =
static_cast<T
>(raw[k]);
53 static_assert(ref,
"Constructor cannot be used with vector values");
59 static_assert(!ref,
"Constructor cannot be used with vector references");
65 static_assert(!ref,
"Constructor cannot be used with vector references");
66 for (
size_t k = 0; k < d; k++)
73 static_assert(!ref,
"Constructor cannot be used with vector references");
74 static_assert(d == 2,
"Invalid constructor for dimension");
82 static_assert(!ref,
"Constructor cannot be used with vector references");
83 static_assert(d == 3,
"Invalid constructor for dimension");
90 Vec(T v1, T v2, T v3, T v4)
92 static_assert(!ref,
"Constructor cannot be used with vector references");
93 static_assert(d == 4,
"Invalid constructor for dimension");
107 static_assert(!ref,
"Cannot be used with vector references");
113 for (
size_t k = 0; k < d; k++)
120 for (
size_t k = 0; k < d; k++)
121 if (
x[k] != other[k])
128 return !(*
this != other);
146 std::array<T, d> data;
147 for (
size_t k = 0; k < d; k++)
148 data[k] =
x[k] *
x[k];
149 return std::accumulate(data.cbegin(), data.cend(),
static_cast<T
>(0));
182 T one_over_val = T(1) / val;
183 for (
size_t k = 0; k < d; k++)
184 x[k] *= one_over_val;
190 for (
size_t k = 0; k < d; k++)
197 for (
size_t k = 0; k < d; k++)
204 for (
size_t k = 0; k < d; k++)
211 for (
size_t k = 0; k < d; k++)
218 for (
size_t k = 0; k < d; k++)
226 for (
size_t k = 0; k < d; k++)
234 for (
size_t k = 0; k < d; k++)
235 equal &= (
x[k] == other[k]);
241 return !(*
this == other);
294 std::array<T, d> data;
295 for (
size_t k = 0; k < d; k++)
296 data[k] =
x[k] * o[k];
297 return std::accumulate(data.cbegin(), data.cend(),
static_cast<T
>(0));
303 static_assert(d == 3,
"Invalid constructor for dimension");
return T_VEC_VALUE(
x[1] * o[2] -
x[2] * o[1],
x[2] * o[0] -
x[0] * o[2],
x[0] * o[1] -
x[1] * o[0]);
309 static_assert(d == 3,
"Invalid constructor for dimension");
319 static_assert(d == 3,
"Invalid constructor for dimension");
323 return acos(
dot(o) / l);
332 static_assert(d == 3,
"Invalid constructor for dimension");
333 double c = cos(
angle);
334 double s = sin(
angle);
335 return c * (*this) + (1 - c) *
dot(axis) * axis - s *
cross(axis);
343 out <<
"(" << val[0];
344 for (
size_t k = 1; k < d; k++)
345 out <<
"," << val[k];
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Vec & operator=(const Vec< T2, d, refother > &other)
T dot(const Vec< T, d, refother > &o) const
T & operator[](const int i)
static Vec< T, d, false > copy(T2 *raw)
Initialize vector value using raw memory.
bool operator!=(const Vec< Tother, d, refother > &other) const
friend T_VEC_VALUE operator*(T s, const Vec &v)
Vec()
Empty constructor (this is invalid for a reference type)
T length2() const
Square of euclidean (2) norm.
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Vec(T *raw)
Initialize vector to be reference to plain raw data.
Vec(T v1, T v2, T v3, T v4)
Convenience 4 vector initialization (only for d==4)
Vec & operator/=(const Vec< T, d, refother > &other)
Vec & operator+=(const Vec< T, d, refother > &other)
Vec(const Vec< T2, d, refother > &other)
Copy construct. Only valid if we are not going to be a reference data!
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
bool operator==(const Vec< T, d, refother > &other) const
Vec(T v1, T v2, T v3)
Convenience 3 vector initialization (only for d==3)
bool operator!=(const Vec< T, d, refother > &other) const
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
bool operator==(const Vec< Tother, d, refother > &other) const
Vec(T v0)
Convenience constant vector initialization (valid for any d)
Vec & operator*=(const Vec< T, d, refother > &other)
Vec< T, d, false > T_VEC_VALUE
T angle(const Vec< T, 3, refother > &o) const
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
T_VEC_VALUE operator-() const
T_VEC_VALUE orthogonal() const
T normalize()
Normalize in place and return the 2-norm before normalization.
T length() const
Euclidean (2) norm.
static_if< ref, T *, std::array< T, d > >::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Vec(T v1, T v2)
Convenience 2 vector initialization (only for d==2)
T_VEC_VALUE operator*(T s) const
Vec & operator/=(const T val)
T_VEC_VALUE operator/(T s) const
Vec & operator*=(const T val)
Vec & operator-=(const Vec< T, d, refother > &other)
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
const T & operator[](const int i) const
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Static conditional type true case.