KSeExpr 6.0.0.0
Vec.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2// SPDX-License-Identifier: LicenseRef-Apache-2.0
3// SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6#pragma once
7
8#include <array>
9#include <cmath>
10#include <iostream>
11#include <numeric>
12#include <type_traits>
13
14
15//#############################################################################
16// Template Metaprogramming Helpers
17namespace KSeExpr
18{
20template<bool c, class T1, class T2> struct static_if {
21 using TYPE = T1;
22};
24template<class T1, class T2> struct static_if<false, T1, T2> {
25 using TYPE = T2;
26};
27
30template<class T, size_t d, bool ref = false> class Vec
31{
34
35public:
38
40 template<class T2> static Vec<T, d, false> copy(T2 *raw)
41 {
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]);
46 return ret;
47 }
48
50 explicit Vec(T *raw)
51 : x(raw)
52 {
53 static_assert(ref, "Constructor cannot be used with vector values");
54 }
55
58 {
59 static_assert(!ref, "Constructor cannot be used with vector references");
60 }
61
64 {
65 static_assert(!ref, "Constructor cannot be used with vector references");
66 for (size_t k = 0; k < d; k++)
67 x[k] = v0;
68 }
69
72 {
73 static_assert(!ref, "Constructor cannot be used with vector references");
74 static_assert(d == 2, "Invalid constructor for dimension");
75 x[0] = v1;
76 x[1] = v2;
77 }
78
80 Vec(T v1, T v2, T v3)
81 {
82 static_assert(!ref, "Constructor cannot be used with vector references");
83 static_assert(d == 3, "Invalid constructor for dimension");
84 x[0] = v1;
85 x[1] = v2;
86 x[2] = v3;
87 }
88
90 Vec(T v1, T v2, T v3, T v4)
91 {
92 static_assert(!ref, "Constructor cannot be used with vector references");
93 static_assert(d == 4, "Invalid constructor for dimension");
94 x[0] = v1;
95 x[1] = v2;
96 x[2] = v3;
97 x[3] = v4;
98 }
99 // Changed this to default. This is safe! for reference case it makes another reference
100 // for value it copies
102 // Vec(const Vec&)
103
105 template<class T2, bool refother> Vec(const Vec<T2, d, refother> &other)
106 {
107 static_assert(!ref, "Cannot be used with vector references");
108 *this = other;
109 }
110
111 template<class T2, bool refother> Vec &operator=(const Vec<T2, d, refother> &other)
112 {
113 for (size_t k = 0; k < d; k++)
114 x[k] = other[k];
115 return *this;
116 }
117
118 template<class Tother, bool refother> bool operator==(const Vec<Tother, d, refother> &other) const
119 {
120 for (size_t k = 0; k < d; k++)
121 if (x[k] != other[k])
122 return false;
123 return true;
124 }
125
126 template<class Tother, bool refother> bool operator!=(const Vec<Tother, d, refother> &other) const
127 {
128 return !(*this != other);
129 }
130
131 // non-const element access
132 T &operator[](const int i)
133 {
134 return x[i];
135 }
136
137 // const element access
138 const T &operator[](const int i) const
139 {
140 return x[i];
141 }
142
144 T length2() const
145 {
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));
150 }
151
153 T length() const
154 {
155 return sqrt(length2());
156 }
157
160 {
161 T l = length2();
162 if (l) {
163 l = sqrt(l);
164 *this /= l;
165 } else {
166 *this = T_VEC_VALUE((T)0);
167 x[0] = 1;
168 }
169 return l;
170 }
171
174 {
175 Vec<T, d, false> other(*this);
177 return other;
178 }
179
180 Vec &operator/=(const T val)
181 {
182 T one_over_val = T(1) / val;
183 for (size_t k = 0; k < d; k++)
184 x[k] *= one_over_val;
185 return *this;
186 }
187
188 Vec &operator*=(const T val)
189 {
190 for (size_t k = 0; k < d; k++)
191 x[k] *= val;
192 return *this;
193 }
194
195 template<bool refother> Vec &operator+=(const Vec<T, d, refother> &other)
196 {
197 for (size_t k = 0; k < d; k++)
198 x[k] += other[k];
199 return *this;
200 }
201
202 template<bool refother> Vec &operator-=(const Vec<T, d, refother> &other)
203 {
204 for (size_t k = 0; k < d; k++)
205 x[k] -= other[k];
206 return *this;
207 }
208
209 template<bool refother> Vec &operator*=(const Vec<T, d, refother> &other)
210 {
211 for (size_t k = 0; k < d; k++)
212 x[k] *= other[k];
213 return *this;
214 }
215
216 template<bool refother> Vec &operator/=(const Vec<T, d, refother> &other)
217 {
218 for (size_t k = 0; k < d; k++)
219 x[k] /= other[k];
220 return *this;
221 }
222
224 {
225 T_VEC_VALUE val(*this);
226 for (size_t k = 0; k < d; k++)
227 val[k] = -val[k];
228 return val;
229 }
230
231 template<bool refother> bool operator==(const Vec<T, d, refother> &other) const
232 {
233 bool equal = true;
234 for (size_t k = 0; k < d; k++)
235 equal &= (x[k] == other[k]);
236 return equal;
237 }
238
239 template<bool refother> bool operator!=(const Vec<T, d, refother> &other) const
240 {
241 return !(*this == other);
242 }
243
245 {
246 T_VEC_VALUE val(*this);
247 val *= s;
248 return val;
249 }
250
252 {
253 T_VEC_VALUE val(*this);
254 val /= s;
255 return val;
256 }
257
258 template<bool refother> T_VEC_VALUE operator+(const Vec<T, d, refother> &other) const
259 {
260 T_VEC_VALUE val(*this);
261 val += other;
262 return val;
263 }
264
265 template<bool refother> T_VEC_VALUE operator-(const Vec<T, d, refother> &other) const
266 {
267 T_VEC_VALUE val(*this);
268 val -= other;
269 return val;
270 }
271
272 template<bool refother> T_VEC_VALUE operator*(const Vec<T, d, refother> &other) const
273 {
274 T_VEC_VALUE val(*this);
275 val *= other;
276 return val;
277 }
278
279 template<bool refother> T_VEC_VALUE operator/(const Vec<T, d, refother> &other) const
280 {
281 T_VEC_VALUE val(*this);
282 val /= other;
283 return val;
284 }
285
286 friend T_VEC_VALUE operator*(T s, const Vec &v)
287 {
288 return v * s;
289 }
290
292 template<bool refother> T dot(const Vec<T, d, refother> &o) const
293 {
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));
298 }
299
301 template<bool refother> T_VEC_VALUE cross(const Vec<T, 3, refother> &o) const
302 {
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]);
304 }
305
308 {
309 static_assert(d == 3, "Invalid constructor for dimension");
310 return T_VEC_VALUE(x[1] + x[2], x[2] - x[0], -x[0] - x[1]);
311 }
312
317 template<bool refother> T angle(const Vec<T, 3, refother> &o) const
318 {
319 static_assert(d == 3, "Invalid constructor for dimension");
320 T l = length() * o.length();
321 if (l == 0)
322 return 0;
323 return acos(dot(o) / l);
324 }
325
330 template<bool refother> T_VEC_VALUE rotateBy(const Vec<T, 3, refother> &axis, T angle) const
331 {
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);
336 }
337};
338
340template<class T, size_t d, bool r> std::ostream &operator<<(std::ostream &out, const Vec<T, d, r> &val)
341{
342 if (d > 0)
343 out << "(" << val[0];
344 for (size_t k = 1; k < d; k++)
345 out << "," << val[k];
346 out << ")";
347 return out;
348}
349
374} // namespace KSeExpr
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Definition Vec.h:265
Vec & operator/=(const T val)
Definition Vec.h:180
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Definition Vec.h:258
T dot(const Vec< T, d, refother > &o) const
Definition Vec.h:292
bool operator!=(const Vec< Tother, d, refother > &other) const
Definition Vec.h:126
friend T_VEC_VALUE operator*(T s, const Vec &v)
Definition Vec.h:286
Vec()
Empty constructor (this is invalid for a reference type)
Definition Vec.h:57
T length2() const
Square of euclidean (2) norm.
Definition Vec.h:144
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Definition Vec.h:272
Vec(T *raw)
Initialize vector to be reference to plain raw data.
Definition Vec.h:50
Vec(T v1, T v2, T v3, T v4)
Convenience 4 vector initialization (only for d==4)
Definition Vec.h:90
static Vec< T, d, false > copy(T2 *raw)
Initialize vector value using raw memory.
Definition Vec.h:40
Vec & operator*=(const T val)
Definition Vec.h:188
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Definition Vec.h:173
Vec(const Vec< T2, d, refother > &other)
Copy construct. Only valid if we are not going to be a reference data!
Definition Vec.h:105
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
Definition Vec.h:279
bool operator==(const Vec< T, d, refother > &other) const
Definition Vec.h:231
Vec & operator+=(const Vec< T, d, refother > &other)
Definition Vec.h:195
Vec(T v1, T v2, T v3)
Convenience 3 vector initialization (only for d==3)
Definition Vec.h:80
Vec & operator=(const Vec< T2, d, refother > &other)
Definition Vec.h:111
bool operator!=(const Vec< T, d, refother > &other) const
Definition Vec.h:239
bool operator==(const Vec< Tother, d, refother > &other) const
Definition Vec.h:118
Vec(T v0)
Convenience constant vector initialization (valid for any d)
Definition Vec.h:63
Vec< T, d, false > T_VEC_VALUE
Definition Vec.h:36
Vec & operator/=(const Vec< T, d, refother > &other)
Definition Vec.h:216
T angle(const Vec< T, 3, refother > &o) const
Definition Vec.h:317
T & operator[](const int i)
Definition Vec.h:132
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition Vec.h:330
T_VEC_VALUE operator-() const
Definition Vec.h:223
T_VEC_VALUE orthogonal() const
Definition Vec.h:307
T normalize()
Normalize in place and return the 2-norm before normalization.
Definition Vec.h:159
T length() const
Euclidean (2) norm.
Definition Vec.h:153
Vec(T v1, T v2)
Convenience 2 vector initialization (only for d==2)
Definition Vec.h:71
T_VEC_VALUE operator*(T s) const
Definition Vec.h:244
T_VEC_VALUE operator/(T s) const
Definition Vec.h:251
static_if< ref, T *, std::array< T, d > >::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Definition Vec.h:33
Vec & operator*=(const Vec< T, d, refother > &other)
Definition Vec.h:209
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
Definition Vec.h:301
const T & operator[](const int i) const
Definition Vec.h:138
Vec & operator-=(const Vec< T, d, refother > &other)
Definition Vec.h:202
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Definition Vec.h:340
Static conditional type true case.
Definition Vec.h:20