Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tfVector.h
1/*******************************************************************************
2 * This file is part of Tissue Forge.
3 * Copyright (c) 2022-2024 T.J. Sego
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ******************************************************************************/
19
20#ifndef _SOURCE_TYPES_TFVECTOR_H_
21#define _SOURCE_TYPES_TFVECTOR_H_
22
23#include <tfError.h>
24
25#include <Magnum/Magnum.h>
26#include <Magnum/Math/Vector.h>
27
28#include <string>
29#include <vector>
30
31
32namespace TissueForge::types {
33
34
35 template<std::size_t size, class T> using VectorBase = Magnum::Math::Vector<size, T>;
36
37 template<std::size_t size, class T>
38 class TVectorS : public VectorBase<size, T> {
39 public:
41 static TVectorS<size, T>& from(T* data) { return *reinterpret_cast<TVectorS<size, T>*>(&VectorBase<size, T>::from(data)); }
42
44 static const TVectorS<size, T>& from(const T* data) { return *reinterpret_cast<const TVectorS<size, T>*>(&VectorBase<size, T>::from(data)); }
45
47 template<std::size_t otherSize> constexpr static TVectorS<size, T> pad(const TVectorS<otherSize, T>& a, T value = T()) {
48 return (TVectorS<size, T>)VectorBase<size, T>::pad<otherSize>(a, value);
49 }
50
51 TVectorS() : VectorBase<size, T>() {}
52
53 TVectorS(const TVectorS<size, T>&) = default;
54
55 template<class ...U, class V = typename std::enable_if<sizeof...(U)+1 == size, T>::type> constexpr TVectorS(T first, U... next) : VectorBase<size, T>(first, next...) {}
56
58 T* data() { return VectorBase<size, T>::data(); }
59
61 constexpr const T* data() const { return VectorBase<size, T>::data(); }
62
63 T& operator[](std::size_t pos) { return VectorBase<size, T>::operator[](pos); }
64 constexpr T operator[](std::size_t pos) const { return VectorBase<size, T>::operator[](pos); }
65
66 bool operator==(const VectorBase<size, T>& other) const { return VectorBase<size, T>::operator==(other); }
67
68 bool operator!=(const VectorBase<size, T>& other) const { return VectorBase<size, T>::operator!=(other); }
69
70 TVectorS<size, T>& operator+=(const TVectorS<size, T>& other) {
71 TVectorS<size, T>::operator+=(other);
72 return *this;
73 }
74
75 TVectorS<size, T> operator+(const TVectorS<size, T>& other) const { return (TVectorS<size, T>)VectorBase<size, T>::operator+((VectorBase<size, T>)other); }
76
77 TVectorS<size, T>& operator-=(const TVectorS<size, T>& other) {
78 TVectorS<size, T>::operator-=(other);
79 return *this;
80 }
81
82 TVectorS<size, T> operator-(const TVectorS<size, T>& other) const { return (TVectorS<size, T>)VectorBase<size, T>::operator-((VectorBase<size, T>)other); }
83
84 TVectorS<size, T>& operator*=(T scalar) {
85 TVectorS<size, T>::operator*=(scalar);
86 return *this;
87 }
88
89 TVectorS<size, T> operator*(T scalar) const { return TVectorS<size, T>(VectorBase<size, T>::operator*(scalar)); }
90
91 TVectorS<size, T>& operator/=(T scalar) {
92 VectorBase<size, T>::operator/=(scalar);
93 return *this;
94 }
95
96 TVectorS<size, T> operator/(T scalar) const { return TVectorS<size, T>(VectorBase<size, T>::operator/(scalar)); }
97
98 TVectorS<size, T>& operator*=(const VectorBase<size, T>& other) {
99 VectorBase<size, T>::operator*=(other);
100 return *this;
101 }
102
103 TVectorS<size, T> operator*(const VectorBase<size, T>& other) const { return (TVectorS<size, T>)VectorBase<size, T>::operator*((VectorBase<size, T>)other); }
104
105 TVectorS<size, T>& operator/=(const VectorBase<size, T>& other) {
106 VectorBase<size, T>::operator/=(other);
107 return *this;
108 }
109
110 TVectorS<size, T> operator/(const VectorBase<size, T>& other) const {
111 return TVectorS<size, T>(VectorBase<size, T>::operator/(other));
112 }
113
115 T dot() const { return VectorBase<size, T>::dot(); }
116
118 T dot(const TVectorS<size, T>& other) const { return Magnum::Math::dot(*this, other); }
119
121 T length() const { return VectorBase<size, T>::length(); }
122
124 template<class U = T> typename std::enable_if<std::is_floating_point<U>::value, T>::type
125 lengthInverted() const { return VectorBase<size, T>::lengthInverted(); }
126
128 template<class U = T> typename std::enable_if<std::is_floating_point<U>::value, VectorBase<size, T>>::type
129 normalized() const { return VectorBase<size, T>::normalized(); }
130
132 template<class U = T> typename std::enable_if<std::is_floating_point<U>::value, VectorBase<size, T>>::type
133 resized(T length) const { return VectorBase<size, T>::resized(length); }
134
136 template<class U = T> typename std::enable_if<std::is_floating_point<U>::value, VectorBase<size, T>>::type
137 projected(const VectorBase<size, T>& line) const { return VectorBase<size, T>::projected(line); }
138
140 template<class U = T> typename std::enable_if<std::is_floating_point<U>::value, VectorBase<size, T>>::type
141 projectedOntoNormalized(const VectorBase<size, T>& line) const { return VectorBase<size, T>::projectedOntoNormalized(line); }
142
144 constexpr TVectorS<size, T> flipped() const { return VectorBase<size, T>::flipped(); }
145
147 T sum() const { return VectorBase<size, T>::sum(); }
148
150 T product() const { return VectorBase<size, T>::product(); }
151
153 T min() const { return VectorBase<size, T>::min(); }
154
156 T max() const { return VectorBase<size, T>::max(); }
157
159 std::pair<T, T> minmax() const { return VectorBase<size, T>::minmax(); }
160
161 TVectorS<size, T>(const VectorBase<size, T> &other) : VectorBase<size, T>() {
162 for(int i = 0; i < other.Size; ++i) this->_data[i] = other[i];
163 }
164
165 operator VectorBase<size, T>*() { return static_cast<VectorBase<size, T>*>(this); }
166
167 operator VectorBase<size, T>&() { return *static_cast<VectorBase<size, T>*>(this); }
168
169 #ifdef SWIGPYTHON
170 T __getitem__(std::size_t i) { return this->operator[](i); }
171 void __setitem__(std::size_t i, const T &val) { this->operator[](i) = val; }
172 #endif
173
174 };
175
176 #define REVISED_MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(size, Type, MagnumImplType) \
177 \
178 static Type<T>& from(T* data) { \
179 return *reinterpret_cast<Type<T>*>(data); \
180 } \
181 \
182 \
183 static const Type<T>& from(const T* data) { \
184 return *reinterpret_cast<const Type<T>*>(data); \
185 } \
186 \
187
188 \
189 template<std::size_t otherSize> \
190 constexpr static Type<T> pad(const Type<T>& a, T value = T()) { \
191 return MagnumImplType<T>::pad(a, value); \
192 } \
193 \
194 template<class U = T> \
195 typename std::enable_if<std::is_signed<U>::value, Type<T>>::type \
196 operator-() const { \
197 return MagnumImplType<T>::operator-(); \
198 } \
199 Type<T>& operator+=(const Type<T>& other) { \
200 MagnumImplType<T>::operator+=(other); \
201 return *this; \
202 } \
203 Type<T> operator+(const Type<T>& other) const { \
204 return MagnumImplType<T>::operator+(other); \
205 } \
206 Type<T>& operator-=(const Type<T>& other) { \
207 MagnumImplType<T>::operator-=(other); \
208 return *this; \
209 } \
210 Type<T> operator-(const Type<T>& other) const { \
211 return MagnumImplType<T>::operator-(other); \
212 } \
213 Type<T>& operator*=(T number) { \
214 MagnumImplType<T>::operator*=(number); \
215 return *this; \
216 } \
217 Type<T> operator*(T number) const { \
218 return MagnumImplType<T>::operator*(number); \
219 } \
220 Type<T>& operator/=(T number) { \
221 MagnumImplType<T>::operator/=(number); \
222 return *this; \
223 } \
224 Type<T> operator/(T number) const { \
225 return MagnumImplType<T>::operator/(number); \
226 } \
227 Type<T>& operator*=(const Type<T>& other) { \
228 MagnumImplType<T>::operator*=(other); \
229 return *this; \
230 } \
231 Type<T> operator*(const Type<T>& other) const { \
232 return MagnumImplType<T>::operator*(other); \
233 } \
234 Type<T>& operator/=(const Type<T>& other) { \
235 MagnumImplType<T>::operator/=(other); \
236 return *this; \
237 } \
238 Type<T> operator/(const Type<T>& other) const { \
239 return MagnumImplType<T>::operator/(other); \
240 } \
241 \
242 \
243 template<class U = T> \
244 typename std::enable_if<std::is_floating_point<U>::value, T>::type \
245 length() const { return MagnumImplType<T>::length(); } \
246 \
247 \
248 template<class U = T> \
249 typename std::enable_if<std::is_floating_point<U>::value, Type<T>>::type \
250 normalized() const { return MagnumImplType<T>::normalized(); } \
251 \
252 \
253 template<class U = T> \
254 typename std::enable_if<std::is_floating_point<U>::value, Type<T>>::type \
255 resized(T length) const { \
256 return MagnumImplType<T>::resized(length); \
257 } \
258 \
259 \
260 template<class U = T> \
261 typename std::enable_if<std::is_floating_point<U>::value, Type<T>>::type \
262 projected(const Type<T>& other) const { \
263 return MagnumImplType<T>::projected(other); \
264 } \
265 \
266 \
267 template<class U = T> \
268 typename std::enable_if<std::is_floating_point<U>::value, Type<T>>::type \
269 projectedOntoNormalized(const Type<T>& other) const { \
270 return MagnumImplType<T>::projectedOntoNormalized(other); \
271 } \
272 \
273 \
274 constexpr Type<T> flipped() const { return MagnumImplType<T>::flipped(); } \
275 \
276 \
277 T dot() const { return Magnum::Math::dot(*this, *this); } \
278 \
279 \
280 T dot(const Type<T>& other) const { return Magnum::Math::dot(*this, other); } \
281 \
282 \
283 template<class U = T> \
284 typename std::enable_if<std::is_floating_point<U>::value, T>::type \
285 angle(const Type<T>& other) const { \
286 Type<T> a = this->isNormalized() ? *this : this->normalized(); \
287 Type<T> b = other.isNormalized() ? other : other.normalized(); \
288 return T(Magnum::Math::angle(a, b)); \
289 } \
290 T& operator[](std::size_t pos) { return MagnumImplType<T>::operator[](pos); } \
291 constexpr T operator[](std::size_t pos) const { \
292 return MagnumImplType<T>::operator[](pos); \
293 } \
294
295 #define SWIGPYTHON_MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(size, Type) \
296 T _getitem(int i) { \
297 if(i < 0) return _getitem(size - 1 + i); \
298 return this->operator[](i); \
299 } \
300 void _setitem(int i, const T &val) { \
301 if(i < 0) return _setitem(size - 1 + i, val); \
302 this->operator[](i) = val; \
303 } \
304 int __len__() { return size; } \
305 \
306 \
307 static Type<T>& fromData(T* data) { return Type<T>::from(data); } \
308 \
309 \
310 static const Type<T>& fromData(const T* data) { return Type<T>::from(data); } \
311 std::vector<T>& asVector() { \
312 std::vector<T> *result = new std::vector<T>(*this); \
313 return *result; \
314 } \
315 \
316 Type<T>& operator+=(const std::vector<T>& other) { \
317 Type<T>::operator+=(Type<T>(other)); \
318 return *this; \
319 } \
320 Type<T> operator+(const std::vector<T>& other) const { \
321 return Type<T>::operator+(Type<T>(other)); \
322 } \
323 Type<T>& operator-=(const std::vector<T>& other) { \
324 Type<T>::operator-=(Type<T>(other)); \
325 return *this; \
326 } \
327 Type<T> operator-(const std::vector<T>& other) const { \
328 return Type<T>::operator-(Type<T>(other)); \
329 } \
330 Type<T>& operator*=(const std::vector<T>& other) { \
331 Type<T>::operator*=(Type<T>(other)); \
332 return *this; \
333 } \
334 Type<T> operator*(const std::vector<T>& other) const { \
335 return Type<T>::operator*(Type<T>(other)); \
336 } \
337 Type<T>& operator/=(const std::vector<T>& other) { \
338 Type<T>::operator/=(Type<T>(other)); \
339 return *this; \
340 } \
341 Type<T> operator/(const std::vector<T>& other) const { \
342 return Type<T>::operator/(Type<T>(other)); \
343 } \
344
345
346 #define MAGNUM_BASE_VECTOR_CAST_METHODS(size, Type, MagnumImplType) \
347 template<class U = T> \
348 Type(const MagnumImplType<U> &other) : MagnumImplType<T>(other) {} \
349 template<class U = T> \
350 Type(const MagnumImplType<U> *other) : MagnumImplType<T>(*other) {} \
351 template<class U = T> \
352 operator MagnumImplType<U>*() { \
353 return static_cast<MagnumImplType<U>*>(this); \
354 } \
355 template<class U = T> \
356 operator const MagnumImplType<U>*() { \
357 return static_cast<const MagnumImplType<U>*>(this); \
358 } \
359 \
360 template<class U = T> \
361 Type(const VectorBase<size, U> &other) : MagnumImplType<T>(other) {} \
362 \
363 Type(const std::vector<T> &v) : MagnumImplType<T>() { \
364 for(int i = 0; i < size; ++i) this->_data[i] = v[i]; \
365 } \
366 operator std::vector<T>&() const { \
367 std::vector<T> *result = new std::vector<T>(std::begin(this->_data), \
368 std::end(this->_data)); \
369 return *result; \
370 } \
371
372}
373
374template<std::size_t size, typename T>
375inline std::ostream& operator<<(std::ostream& os, const TissueForge::types::TVectorS<size, T>& vec)
376{
377 os << std::string("{") << vec[0];
378 for(int i = 1; i < vec.Size; ++i) os << std::string(",") << vec[i];
379 os << std::string("}");
380 return os;
381}
382
383
384#define TF_VECTOR_IMPL_OSTREAM(type) \
385 template<typename T> \
386 inline std::ostream& operator<<(std::ostream& os, const type<T>& vec) \
387 { \
388 os << std::string("{") << vec[0]; \
389 for(int i = 1; i < vec.Size; ++i) os << std::string(",") << vec[i]; \
390 os << std::string("}"); \
391 return os; \
392 } \
393
394#endif // _SOURCE_TYPES_TFVECTOR_H_
Definition tfVector.h:38
constexpr TVectorS< size, T > flipped() const
Definition tfVector.h:144
T product() const
Definition tfVector.h:150
T * data()
Definition tfVector.h:58
std::enable_if< std::is_floating_point< U >::value, VectorBase< size, T > >::type resized(T length) const
Definition tfVector.h:133
std::enable_if< std::is_floating_point< U >::value, T >::type lengthInverted() const
Definition tfVector.h:125
static TVectorS< size, T > & from(T *data)
Definition tfVector.h:41
T dot() const
Definition tfVector.h:115
static const TVectorS< size, T > & from(const T *data)
Definition tfVector.h:44
std::enable_if< std::is_floating_point< U >::value, VectorBase< size, T > >::type projectedOntoNormalized(const VectorBase< size, T > &line) const
Definition tfVector.h:141
T sum() const
Definition tfVector.h:147
T max() const
Definition tfVector.h:156
T min() const
Definition tfVector.h:153
T length() const
Definition tfVector.h:121
T dot(const TVectorS< size, T > &other) const
Definition tfVector.h:118
std::enable_if< std::is_floating_point< U >::value, VectorBase< size, T > >::type normalized() const
Definition tfVector.h:129
std::enable_if< std::is_floating_point< U >::value, VectorBase< size, T > >::type projected(const VectorBase< size, T > &line) const
Definition tfVector.h:137
constexpr const T * data() const
Definition tfVector.h:61
std::pair< T, T > minmax() const
Definition tfVector.h:159
static constexpr TVectorS< size, T > pad(const TVectorS< otherSize, T > &a, T value=T())
Definition tfVector.h:47
Native Tissue Forge type definitions.
Definition tfMatrix.h:33