ACF $AcfVersion:0$
TMathVectorWrap.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// ACF includes
6#include <iser/IArchive.h>
7#include <iser/CArchiveTag.h>
8#include <imath/imath.h>
9
10
11namespace imath
12{
13
14
18template <typename Base>
19class TMathVectorWrap: public Base
20{
21public:
22 typedef Base BaseClass;
23
28
32 TMathVectorWrap(const Base& vector);
33
37 void Clear();
38
42 void Translate(const TMathVectorWrap<Base>& vector);
43
48
53
57 bool IsNull(typename Base::ElementType tolerance = I_BIG_EPSILON) const;
58
62 typename Base::ElementType GetDotProduct(const TMathVectorWrap<Base>& vector) const;
63
67 typename Base::ElementType GetLength2() const;
68
72 typename Base::ElementType GetLength() const;
73
77 typename Base::ElementType GetDistance2(const TMathVectorWrap<Base>& vector) const;
78
82 typename Base::ElementType GetDistance(const TMathVectorWrap<Base>& vector) const;
83
89 bool Normalize(typename Base::ElementType length = 1.0);
95 bool GetNormalized(TMathVectorWrap<Base>& result, typename Base::ElementType length = 1.0) const;
96
100 bool Serialize(iser::IArchive& archive);
101
102 bool operator==(const TMathVectorWrap<Base>& vector) const;
103 bool operator!=(const TMathVectorWrap<Base>& vector) const;
104 bool operator<(const TMathVectorWrap<Base>& vector) const;
105 bool operator>(const TMathVectorWrap<Base>& vector) const;
106 bool operator<=(const TMathVectorWrap<Base>& vector) const;
107 bool operator>=(const TMathVectorWrap<Base>& vector) const;
108
110
113 TMathVectorWrap<Base> operator*(typename Base::ElementType scalar) const;
114 TMathVectorWrap<Base> operator/(typename Base::ElementType scalar) const;
115
117
120 TMathVectorWrap<Base>& operator*=(typename Base::ElementType scalar);
121 TMathVectorWrap<Base>& operator/=(typename Base::ElementType scalar);
122
123 operator Base() const;
124};
125
126
127// inline constructors
128
129template <typename Base>
133
134
135template <typename Base>
137: BaseClass(vector)
138{
139}
140
141
142// inline methods
143
144template <typename Base>
146{
147 int elementsCount = BaseClass::GetElementsCount();
148 for (int i = 0; i < elementsCount; ++i){
149 BaseClass::SetElement(i, 0.0);
150 }
151}
152
153
154template <typename Base>
156{
157 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
158 for (int i = 0; i < elementsCount; ++i){
159 BaseClass::GetElementRef(i) += vector.GetElement(i);
160 }
161}
162
163
164template <typename Base>
166{
167 return *this + vector;
168}
169
170
171template <typename Base>
173{
174 result = *this + vector;
175}
176
177
178template <typename Base>
179inline bool TMathVectorWrap<Base>::IsNull(typename Base::ElementType tolerance) const
180{
181 return GetLength2() <= tolerance * tolerance;
182}
183
184
185template <typename Base>
186inline typename Base::ElementType TMathVectorWrap<Base>::GetDotProduct(const TMathVectorWrap<Base>& vector) const
187{
188 typename Base::ElementType retVal = 0.0;
189
190 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
191 for (int i = 0; i < elementsCount; ++i){
192 retVal += BaseClass::GetElement(i) * vector.GetElement(i);
193 }
194
195 return retVal;
196}
197
198
199template <typename Base>
200inline typename Base::ElementType TMathVectorWrap<Base>::GetLength2() const
201{
202 return GetDotProduct(*this);
203}
204
205
206template <typename Base>
207inline typename Base::ElementType TMathVectorWrap<Base>::GetLength() const
208{
209 return qSqrt(GetLength2());
210}
211
212
213template <typename Base>
214inline typename Base::ElementType TMathVectorWrap<Base>::GetDistance2(const TMathVectorWrap<Base>& vector) const
215{
216 return (*this - vector).GetLength2();
217}
218
219
220template <typename Base>
221inline typename Base::ElementType TMathVectorWrap<Base>::GetDistance(const TMathVectorWrap<Base>& vector) const
222{
223 return qSqrt(GetDistance2(vector));
224}
225
226
227// operators
228
229template <typename Base>
231{
232 int elementsCount = BaseClass::GetElementsCount();
233 if (elementsCount != vector.GetElementsCount()){
234 return false;
235 }
236
237 for (int i = 0; i < elementsCount; ++i){
238 if (BaseClass::GetElement(i) != vector.GetElement(i)){
239 return false;
240 }
241 }
242 return true;
243}
244
245
246template <typename Base>
248{
249 return !operator==(vector);
250}
251
252
253template <typename Base>
255{
256 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
257 for (int i = 0; i < elementsCount; ++i){
258 typename Base::ElementType firstElement = BaseClass::GetElement(i);
259 typename Base::ElementType secondElement = vector.GetElement(i);
260
261 if (firstElement > secondElement){
262 return false;
263 }
264 else if (firstElement < secondElement){
265 return true;
266 }
267 }
268
269 return BaseClass::GetElementsCount() < vector.GetElementsCount();
270}
271
272
273template <typename Base>
275{
276 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
277 for (int i = 0; i < elementsCount; ++i){
278 typename Base::ElementType firstElement = BaseClass::GetElement(i);
279 typename Base::ElementType secondElement = vector.GetElement(i);
280
281 if (firstElement > secondElement){
282 return true;
283 }
284 else if (firstElement < secondElement){
285 return false;
286 }
287 }
288
289 return BaseClass::GetElementsCount() > vector.GetElementsCount();
290}
291
292
293template <typename Base>
295{
296 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
297 for (int i = 0; i < elementsCount; ++i){
298 typename Base::ElementType firstElement = BaseClass::GetElement(i);
299 typename Base::ElementType secondElement = vector.GetElement(i);
300
301 if (firstElement > secondElement){
302 return false;
303 }
304 else if (firstElement < secondElement){
305 return true;
306 }
307 }
308
309 return BaseClass::GetElementsCount() <= vector.GetElementsCount();
310}
311
312
313template <typename Base>
315{
316 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
317 for (int i = 0; i < elementsCount; ++i){
318 typename Base::ElementType firstElement = BaseClass::GetElement(i);
319 typename Base::ElementType secondElement = vector.GetElement(i);
320
321 if (firstElement > secondElement){
322 return true;
323 }
324 else if (firstElement < secondElement){
325 return false;
326 }
327 }
328
329 return BaseClass::GetElementsCount() >= vector.GetElementsCount();
330}
331
332
333template <typename Base>
335{
336 BaseClass::operator=(vector);
337
338 return *this;
339}
340
341
342template <typename Base>
344{
345 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
346 for (int i = 0; i < elementsCount; ++i){
347 BaseClass::GetElementRef(i) += vector.GetElement(i);
348 }
349
350 return *this;
351}
352
353
354template <typename Base>
356{
357 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
358 for (int i = 0; i < elementsCount; ++i){
359 BaseClass::GetElementRef(i) -= vector.GetElement(i);
360 }
361
362 return *this;
363}
364
365
366template <typename Base>
367inline TMathVectorWrap<Base>& TMathVectorWrap<Base>::operator*=(typename Base::ElementType scalar)
368{
369 int elementsCount = BaseClass::GetElementsCount();
370 for (int i = 0; i < elementsCount; ++i){
371 BaseClass::GetElementRef(i) *= scalar;
372 }
373
374 return *this;
375}
376
377
378template <typename Base>
379inline TMathVectorWrap<Base>& TMathVectorWrap<Base>::operator/=(typename Base::ElementType scalar)
380{
381 int elementsCount = BaseClass::GetElementsCount();
382 for (int i = 0; i < elementsCount; ++i){
383 BaseClass::GetElementRef(i) /= scalar;
384 }
385
386 return *this;
387}
388
389
390template <typename Base>
392{
394
395 int elementsCount = BaseClass::GetElementsCount();
396 retVal.SetElementsCount(elementsCount);
397 for (int i = 0; i < elementsCount; ++i){
398 retVal.SetElement(i, -BaseClass::GetElement(i));
399 }
400
401 return *this;
402}
403
404
405template <typename Base>
407{
409
410 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
411 retVal.SetElementsCount(elementsCount);
412 for (int i = 0; i < elementsCount; ++i){
413 retVal.SetElement(i, BaseClass::GetElement(i) + vector.GetElement(i));
414 }
415
416 return retVal;
417}
418
419
420template <typename Base>
422{
424
425 int elementsCount = qMin(BaseClass::GetElementsCount(), vector.GetElementsCount());
426 retVal.SetElementsCount(elementsCount);
427 for (int i = 0; i < elementsCount; ++i){
428 retVal.SetElement(i, BaseClass::GetElement(i) - vector.GetElement(i));
429 }
430
431 return retVal;
432}
433
434
435template <typename Base>
436inline TMathVectorWrap<Base> TMathVectorWrap<Base>::operator*(typename Base::ElementType scalar) const
437{
439
440 int elementsCount = BaseClass::GetElementsCount();
441 retVal.SetElementsCount(elementsCount);
442 for (int i = 0; i < elementsCount; ++i){
443 retVal.SetElement(i, BaseClass::GetElement(i) * scalar);
444 }
445
446 return *this;
447}
448
449
450template <typename Base>
451inline TMathVectorWrap<Base> TMathVectorWrap<Base>::operator/(typename Base::ElementType scalar) const
452{
454
455 int elementsCount = BaseClass::GetElementsCount();
456 retVal.SetElementsCount(elementsCount);
457 for (int i = 0; i < elementsCount; ++i){
458 retVal.SetElement(i, BaseClass::GetElement(i) / scalar);
459 }
460
461 return *this;
462}
463
464
465// public methods
466
467template <typename Base>
468bool TMathVectorWrap<Base>::Normalize(typename Base::ElementType length)
469{
470 typename Base::ElementType isLength = GetLength();
471
472 typename Base::ElementType proportion = isLength / length;
473
474 if (qAbs(proportion) > I_BIG_EPSILON){
475 int elementsCount = BaseClass::GetElementsCount();
476 for (int i = 0; i < elementsCount; ++i){
477 BaseClass::SetElement(i, BaseClass::GetElement(i) / proportion);
478 }
479
480 return true;
481 }
482 else{
483 return false;
484 }
485}
486
487
488template <typename Base>
489bool TMathVectorWrap<Base>::GetNormalized(TMathVectorWrap<Base>& result, typename Base::ElementType length) const
490{
491 typename Base::ElementType isLength = GetLength();
492
493 typename Base::ElementType proportion = isLength / length;
494
495 if (qAbs(proportion) > I_BIG_EPSILON){
496 int elementsCount = BaseClass::GetElementsCount();
497 result.SetElementsCount(elementsCount);
498 for (int i = 0; i < elementsCount; ++i){
499 result.SetElement(i, BaseClass::GetElement(i) / proportion);
500 }
501
502 return true;
503 }
504 else{
505 return false;
506 }
507}
508
509
510template <typename Base>
512{
513 bool retVal = true;
514
515 int elementsCount = BaseClass::GetElementsCount();
516
517 static iser::CArchiveTag elementsTag("Elements", "List of vector element", iser::CArchiveTag::TT_MULTIPLE);
518 static iser::CArchiveTag elementTag("Element", "Single vector element", iser::CArchiveTag::TT_LEAF, &elementsTag);
519
520 retVal = retVal && archive.BeginMultiTag(elementsTag, elementTag, elementsCount);
521
522 if (!retVal){
523 return false;
524 }
525
526 if (!archive.IsStoring()){
527 BaseClass::SetElementsCount(elementsCount);
528 }
529
530 for (int i = 0; i < elementsCount; ++i){
531 retVal = retVal && archive.BeginTag(elementTag);
532 retVal = retVal && archive.Process(BaseClass::GetElementRef(i));
533 retVal = retVal && archive.EndTag(elementTag);
534 }
535
536 retVal = retVal && archive.EndTag(elementsTag);
537
538 return retVal;
539}
540
541
542template <typename Base>
544{
545 return Base(*this);
546}
547
548
549} // namespace imath
550
551
Implementation of mathematical vector with carthesian operations over elements container (vector).
TMathVectorWrap< Base > & operator/=(typename Base::ElementType scalar)
Base::ElementType GetDotProduct(const TMathVectorWrap< Base > &vector) const
Return dot product of two vectors.
bool operator>=(const TMathVectorWrap< Base > &vector) const
TMathVectorWrap< Base > & operator-=(const TMathVectorWrap< Base > &vector)
bool operator<(const TMathVectorWrap< Base > &vector) const
bool GetNormalized(TMathVectorWrap< Base > &result, typename Base::ElementType length=1.0) const
Return normalized vector with the same direction and specified length.
bool IsNull(typename Base::ElementType tolerance=I_BIG_EPSILON) const
Check if this vector is null.
bool operator>(const TMathVectorWrap< Base > &vector) const
bool Serialize(iser::IArchive &archive)
Serialize this vector to specified archive.
TMathVectorWrap< Base > GetTranslated(const TMathVectorWrap< Base > &vector)
Get translated point.
TMathVectorWrap< Base > operator-() const
TMathVectorWrap< Base > operator*(typename Base::ElementType scalar) const
void Clear()
Set all coordinates to zero.
Base::ElementType GetDistance2(const TMathVectorWrap< Base > &vector) const
Return distance square between two vectors.
TMathVectorWrap()
Create an uninitialized point.
TMathVectorWrap< Base > & operator+=(const TMathVectorWrap< Base > &vector)
bool Normalize(typename Base::ElementType length=1.0)
Normalize vector to specified length.
Base::ElementType GetDistance(const TMathVectorWrap< Base > &vector) const
Return distance between two vectors.
TMathVectorWrap< Base > operator+(const TMathVectorWrap< Base > &vector) const
bool operator<=(const TMathVectorWrap< Base > &vector) const
bool operator!=(const TMathVectorWrap< Base > &vector) const
TMathVectorWrap< Base > & operator*=(typename Base::ElementType scalar)
TMathVectorWrap< Base > & operator=(const TMathVectorWrap< Base > &vector)
Base::ElementType GetLength2() const
Return euclidian length square.
bool operator==(const TMathVectorWrap< Base > &vector) const
Base::ElementType GetLength() const
Return euclidian length.
TMathVectorWrap< Base > operator/(typename Base::ElementType scalar) const
void Translate(const TMathVectorWrap< Base > &vector)
Translate the point.
Process tag used to group data in archive stream.
Definition CArchiveTag.h:22
@ TT_LEAF
Leaf tag, it can contain only one primitive element.
Definition CArchiveTag.h:48
@ TT_MULTIPLE
Multiple tag containing variable number of child tags.
Definition CArchiveTag.h:42
Represents an input/output persistence archive for object serialization.
Definition IArchive.h:164
virtual bool Process(bool &value)=0
Processes (reads or writes) a boolean value.
virtual bool EndTag(const CArchiveTag &tag)=0
Ends a tagged section in the archive.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begins a tagged section containing multiple elements of the same type.
virtual bool IsStoring() const =0
Checks if this archive is in storing (writing) or loading (reading) mode.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begins a tagged section in the archive.
static const double I_BIG_EPSILON
Definition istd.h:26
Package with mathematical functions and algebraical primitives.