ICF 3.0.5.47
Technical documentation of ICF Libraries
TFastVector.h
Go to the documentation of this file.
1/********************************************************************************
2** This file is part of the ICF Framework. Copyright (C) Witold Gantzke & Kirill Lepskiy
3** ICF Framework may be used under the terms of the LGPL License v. 2.1 by the Free Software Foundation.
4********************************************************************************/
5
6#ifndef imath_TFastVector_included
7#define imath_TFastVector_included
8
9
10// STL includes
11#include <cstring>
12
13// ICF includes
14#include <iser/IArchive.h>
15#include <iser/CArchiveTag.h>
16
17#include <imath/TVector.h>
18
19
20namespace imath
21{
22
23
27template <int MaxSize, class Element = double>
29{
30public:
31 typedef Element ElementType;
32
33 enum{
34 MAX_ELEMENTS_COUNT = MaxSize
35 };
36
41
45 explicit TFastVector(int componentsCount, const Element& value = Element());
46
51
52 template <int Size>
54 : m_elementsCount(Size)
55 {
56 Q_ASSERT(Size <= MaxSize);
57
58 for (int i = 0; i < Size; ++i){
59 m_elements[i] = vector[i];
60 }
61 }
62
66 int GetElementsCount() const;
67
73 bool SetElementsCount(int count, const Element& value = Element());
74
82 bool EnsureElementsCount(int count, const Element& value = Element());
83
87 const Element& GetElement(int i) const;
88
92 Element& GetElementRef(int i);
93
97 void SetElement(int i, const Element& value);
98
102 void Clear();
103
109 void SetElementsFrom(const TFastVector& vector, const Element& expansionValue = Element());
110
115
120
125
130 void ScaledCumulate(const TFastVector<MaxSize, Element>& vector, Element scale);
131
135 bool IsNull(Element tolerance = I_BIG_EPSILON) const;
136
140 Element GetDotProduct(const TFastVector<MaxSize, Element>& vector) const;
141
145 Element GetLength2() const;
149 Element GetLength() const;
150
154 Element GetDistance2(const TFastVector<MaxSize, Element>& vector) const;
155
159 Element GetDistance(const TFastVector<MaxSize, Element>& vector) const;
160
164 Element GetElementsSum() const;
165
171 bool Normalize(Element length = 1.0);
177 bool GetNormalized(TFastVector<MaxSize, Element>& result, Element length = 1.0) const;
178
187
191 bool Serialize(iser::IArchive& archive);
192
193 bool operator==(const TFastVector<MaxSize, Element>& vector) const;
194 bool operator!=(const TFastVector<MaxSize, Element>& vector) const;
195 bool operator<(const TFastVector<MaxSize, Element>& vector) const;
196 bool operator>(const TFastVector<MaxSize, Element>& vector) const;
197 bool operator<=(const TFastVector<MaxSize, Element>& vector) const;
198 bool operator>=(const TFastVector<MaxSize, Element>& vector) const;
199
201
206
208
213
214 const Element& operator[](int i) const;
215 Element& operator[](int i);
216
217protected:
218 Element m_elements[MaxSize];
220};
221
222
223// inline methods
224
225template <int MaxSize, class Element>
227: m_elementsCount(0)
228{
229}
230
231
232template <int MaxSize, class Element>
233inline TFastVector<MaxSize, Element>::TFastVector(int componentsCount, const Element& value)
234: m_elementsCount(qMin(MaxSize, componentsCount))
235{
236 for (int i = 0; i < m_elementsCount; ++i){
237 m_elements[i] = value;
238 }
239}
240
241
242template <int MaxSize, class Element>
244: m_elementsCount(vector.m_elementsCount)
245{
246 Q_ASSERT(m_elementsCount <= MaxSize);
247
248 std::memcpy(m_elements, vector.m_elements, sizeof(Element) * m_elementsCount);
249}
250
251
252template <int MaxSize, class Element>
254{
255 return m_elementsCount;
256}
257
258
259template <int MaxSize, class Element>
260inline bool TFastVector<MaxSize, Element>::SetElementsCount(int count, const Element& value)
261{
262 if (count <= MaxSize){
263 for (int i = m_elementsCount; i < count; ++i){
264 m_elements[i] = value;
265 }
266
267 m_elementsCount = count;
268
269 return true;
270 }
271 else{
272 return false;
273 }
274}
275
276
277template <int MaxSize, class Element>
278inline bool TFastVector<MaxSize, Element>::EnsureElementsCount(int count, const Element& value)
279{
280 if (count <= MaxSize){
281 if (m_elementsCount < count){
282 for (int i = m_elementsCount; i < count; ++i){
283 m_elements[i] = value;
284 }
285
286 m_elementsCount = count;
287 }
288
289 return true;
290 }
291 else{
292 return false;
293 }
294}
295
296
297template <int MaxSize, class Element>
298inline const Element& TFastVector<MaxSize, Element>::GetElement(int i) const
299{
300 Q_ASSERT(i >= 0);
301 Q_ASSERT(i < m_elementsCount);
302
303 return m_elements[i];
304}
305
306
307template <int MaxSize, class Element>
309{
310 Q_ASSERT(i >= 0);
311 Q_ASSERT(i < m_elementsCount);
312
313 return m_elements[i];
314}
315
316
317template <int MaxSize, class Element>
318inline void TFastVector<MaxSize, Element>::SetElement(int i, const Element& value)
319{
320 Q_ASSERT(i >= 0);
321 Q_ASSERT(i < m_elementsCount);
322
323 m_elements[i] = value;
324}
325
326
327template <int MaxSize, class Element>
329{
330 for (int i = 0; i < m_elementsCount; ++i){
331 m_elements[i] = 0.0;
332 }
333}
334
335
336template <int MaxSize, class Element>
338{
339 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
340 for (int i = 0; i < commonSize; ++i){
341 m_elements[i] += vector.m_elements[i];
342 }
343}
344
345
346template <int MaxSize, class Element>
348{
349 if (m_elementsCount < vector.m_elementsCount){
350 int i = 0;
351 for (; i < m_elementsCount; ++i){
352 m_elements[i] += vector.m_elements[i] * scale;
353 }
354
355 for (; i < vector.m_elementsCount; ++i){
356 m_elements[i] = vector.m_elements[i] * scale;
357 }
358
359 m_elementsCount = vector.m_elementsCount;
360 }
361 else{
362 for (int i = 0; i < vector.m_elementsCount; ++i){
363 m_elements[i] += vector.m_elements[i] * scale;
364 }
365 }
366}
367
368
369template <int MaxSize, class Element>
370void TFastVector<MaxSize, Element>::SetElementsFrom(const TFastVector& vector, const Element& expansionValue)
371{
372 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
373
374 for (int i = 0; i < commonSize; ++i){
375 SetElement(i, vector[i]);
376 }
377
378 for (int i = commonSize; i < m_elementsCount; ++i){
379 SetElement(i, expansionValue);
380 }
381}
382
383
384template <int MaxSize, class Element>
389
390
391template <int MaxSize, class Element>
393{
394
395 result = *this;
396 result.Translate(vector);
397}
398
399
400template <int MaxSize, class Element>
401inline bool TFastVector<MaxSize, Element>::IsNull(Element tolerance) const
402{
403 return GetLength2() <= tolerance * tolerance;
404}
405
406
407template <int MaxSize, class Element>
409{
410 Element retVal = 0.0;
411
412 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
413 for (int i = 0; i < commonSize; ++i){
414 retVal += m_elements[i] * vector.m_elements[i];
415 }
416
417 return retVal;
418}
419
420
421template <int MaxSize, class Element>
423{
424 return GetDotProduct(*this);
425}
426
427
428template <int MaxSize, class Element>
430{
431 return qSqrt(GetLength2());
432}
433
434
435template <int MaxSize, class Element>
437{
438 return (*this - vector).GetLength2();
439}
440
441
442template <int MaxSize, class Element>
444{
445 return qSqrt(GetDistance2(vector));
446}
447
448
449// operators
450
451template <int MaxSize, class Element>
453{
454 if (m_elementsCount != vector.m_elementsCount){
455 return false;
456 }
457
458 for (int i = 0; i < m_elementsCount; ++i){
459 if (m_elements[i] != vector.m_elements[i]){
460 return false;
461 }
462 }
463
464 return true;
465}
466
467
468template <int MaxSize, class Element>
470{
471 return !operator==(vector);
472}
473
474
475template <int MaxSize, class Element>
477{
478 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
479 for (int i = 0; i < commonSize; ++i){
480 if (m_elements[i] > vector.m_elements[i]){
481 return false;
482 }
483 else if (m_elements[i] < vector.m_elements[i]){
484 return true;
485 }
486 }
487
488 return m_elementsCount < vector.m_elementsCount;
489}
490
491
492template <int MaxSize, class Element>
494{
495 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
496 for (int i = 0; i < commonSize; ++i){
497 if (m_elements[i] > vector.m_elements[i]){
498 return true;
499 }
500 else if (m_elements[i] < vector.m_elements[i]){
501 return false;
502 }
503 }
504
505 return m_elementsCount > vector.m_elementsCount;
506}
507
508
509template <int MaxSize, class Element>
511{
512 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
513 for (int i = 0; i < commonSize; ++i){
514 if (m_elements[i] > vector.m_elements[i]){
515 return false;
516 }
517 else if (m_elements[i] < vector.m_elements[i]){
518 return true;
519 }
520 }
521
522 return m_elementsCount <= vector.m_elementsCount;
523}
524
525
526template <int MaxSize, class Element>
528{
529 int commonSize = qMin(m_elementsCount, vector.m_elementsCount);
530 for (int i = 0; i < commonSize; ++i){
531 if (m_elements[i] > vector.m_elements[i]){
532 return true;
533 }
534 else if (m_elements[i] < vector.m_elements[i]){
535 return false;
536 }
537 }
538
539 return m_elementsCount >= vector.m_elementsCount;
540}
541
542
543template <int MaxSize, class Element>
545{
546 m_elementsCount = vector.m_elementsCount;
547 Q_ASSERT(m_elementsCount < MaxSize);
548
549 for (int i = 0; i < m_elementsCount; ++i){
550 m_elements[i] = vector.m_elements[i];
551 }
552
553 return *this;
554}
555
556
557template <int MaxSize, class Element>
559{
560 if (m_elementsCount < vector.m_elementsCount){
561 int i = 0;
562 for (; i < m_elementsCount; ++i){
563 m_elements[i] += vector.m_elements[i];
564 }
565
566 for (; i < vector.m_elementsCount; ++i){
567 m_elements[i] = vector.m_elements[i];
568 }
569
570 m_elementsCount = vector.m_elementsCount;
571 }
572 else{
573 for (int i = 0; i < vector.m_elementsCount; ++i){
574 m_elements[i] += vector.m_elements[i];
575 }
576 }
577
578 return *this;
579}
580
581
582template <int MaxSize, class Element>
584{
585 if (m_elementsCount < vector.m_elementsCount){
586 int i = 0;
587 for (; i < m_elementsCount; ++i){
588 m_elements[i] -= vector.m_elements[i];
589 }
590
591 for (; i < vector.m_elementsCount; ++i){
592 m_elements[i] = -vector.m_elements[i];
593 }
594
595 m_elementsCount = vector.m_elementsCount;
596 }
597 else{
598 for (int i = 0; i < vector.m_elementsCount; ++i){
599 m_elements[i] -= vector.m_elements[i];
600 }
601 }
602
603 return *this;
604}
605
606
607template <int MaxSize, class Element>
609{
610 for (int i = 0; i < m_elementsCount; ++i){
611 m_elements[i] *= scalar;
612 }
613
614 return *this;
615}
616
617
618template <int MaxSize, class Element>
620{
621 for (int i = 0; i < m_elementsCount; ++i){
622 m_elements[i] /= scalar;
623 }
624
625 return *this;
626}
627
628
629template <int MaxSize, class Element>
631{
632 TFastVector<MaxSize, Element> retVal(*this);
633
634 for (int i = 0; i < m_elementsCount; ++i){
635 retVal.m_elements[i] = -m_elements[i];
636 }
637
638 return retVal;
639}
640
641
642template <int MaxSize, class Element>
644{
645 TFastVector<MaxSize, Element> retVal(*this);
646
647 retVal += vector;
648
649 return retVal;
650}
651
652
653template <int MaxSize, class Element>
655{
656 TFastVector<MaxSize, Element> retVal(*this);
657
658 retVal -= vector;
659
660 return retVal;
661}
662
663
664template <int MaxSize, class Element>
666{
667 TFastVector<MaxSize, Element> retVal(*this);
668
669 retVal *= scalar;
670
671 return retVal;
672}
673
674
675template <int MaxSize, class Element>
677{
678 TFastVector<MaxSize, Element> retVal(*this);
679
680 retVal /= scalar;
681
682 return retVal;
683}
684
685
686template <int MaxSize, class Element>
688{
689 Q_ASSERT(i >= 0);
690 Q_ASSERT(i < m_elementsCount);
691
692 return m_elements[i];
693}
694
695
696template <int MaxSize, class Element>
698{
699 Q_ASSERT(i >= 0);
700 Q_ASSERT(i < MaxSize);
701
702 return m_elements[i];
703}
704
705
706// public methods
707
708template <int MaxSize, class Element>
710{
711 Element retVal = 0;
712
713 for (int i = 0; i < m_elementsCount; ++i){
714 retVal += m_elements[i];
715 }
716
717 return retVal;
718}
719
720
721template <int MaxSize, class Element>
723{
724 Element isLength = GetLength();
725
726 Element proportion = isLength / length;
727
728 if (qAbs(proportion) > I_BIG_EPSILON){
729 for (int i = 0; i < m_elementsCount; ++i){
730 m_elements[i] = m_elements[i] / proportion;
731 }
732
733 return true;
734 }
735 else{
736 return false;
737 }
738}
739
740
741template <int MaxSize, class Element>
743{
744 result = *this;
745
746 return result.Normalize(length);
747}
748
749
750template <int MaxSize, class Element>
752{
753 int elementsCount = qMin(GetElementsCount(), vector.GetElementsCount());
754
755 result.SetElementsCount(elementsCount);
756
757 for (int i = 0; i < elementsCount; ++i){
758 result.SetElement(i, qMin(GetElement(i), vector.GetElement(i)));
759 }
760}
761
762
763template <int MaxSize, class Element>
765{
766 int elementsCount = qMin(GetElementsCount(), vector.GetElementsCount());
767
768 result.SetElementsCount(elementsCount);
769
770 for (int i = 0; i < elementsCount; ++i){
771 result.SetElement(i, qMax(GetElement(i), vector.GetElement(i)));
772 }
773}
774
775
776template <int MaxSize, class Element>
778{
779 bool retVal = true;
780
781 static iser::CArchiveTag elementsTag("Elements", "List of vector element", iser::CArchiveTag::TT_MULTIPLE);
782 static iser::CArchiveTag elementTag("Element", "Single vector element", iser::CArchiveTag::TT_LEAF, &elementsTag);
783
784 retVal = retVal && archive.BeginMultiTag(elementsTag, elementTag, m_elementsCount);
785
786 if (!retVal || (m_elementsCount > MaxSize)){
787 if (archive.IsChanging()){
788 m_elementsCount = 0;
789 }
790
791 return false;
792 }
793
794 for (int i = 0; i < m_elementsCount; ++i){
795 retVal = retVal && archive.BeginTag(elementTag);
796 retVal = retVal && archive.Process(m_elements[i]);
797 retVal = retVal && archive.EndTag(elementTag);
798 }
799
800 retVal = retVal && archive.EndTag(elementsTag);
801
802 return retVal;
803}
804
805
806// related global functions
807
808template <int MaxSize, class Element>
809inline size_t qHash(const TFastVector<MaxSize, Element>& v, size_t seed = 0)
810{
811 size_t retVal = seed;
812
813 union{
814 double value;
815 size_t raw;
816 } element;
817 element.raw = 0;
818
819 int elementsCount = v.GetElementsCount();
820 for (int i = 0; i < elementsCount; ++i){
821 element.value = v[i];
822
823 retVal = (retVal << 1) ^ (element.raw + 1);
824 }
825
826 return retVal;
827}
828
829
830} // namespace imath
831
832
833
834#endif // !imath_TFastVector_included
835
836
Simple implementation of fixed-size vector.
Definition TFastVector.h:29
TFastVector< MaxSize, Element > operator-() const
void Clear()
Set all coordinates to zero.
const Element & GetElement(int i) const
Get element at specified i.
bool GetNormalized(TFastVector< MaxSize, Element > &result, Element length=1.0) const
Return normalized vector with the same direction and specified length.
Element GetDistance(const TFastVector< MaxSize, Element > &vector) const
Return distance between two vectors.
TFastVector< MaxSize, Element > & operator-=(const TFastVector< MaxSize, Element > &vector)
Element GetLength2() const
Return euclidian length square.
bool Normalize(Element length=1.0)
Normalize vector to specified length.
void SetElementsFrom(const TFastVector &vector, const Element &expansionValue=Element())
Set elemenents from other vector without resizing.
TFastVector< MaxSize, Element > & operator/=(Element scalar)
bool operator<=(const TFastVector< MaxSize, Element > &vector) const
bool operator>=(const TFastVector< MaxSize, Element > &vector) const
Element GetElementsSum() const
Get simple sum of all elements.
bool SetElementsCount(int count, const Element &value=Element())
Set number of elements.
bool operator==(const TFastVector< MaxSize, Element > &vector) const
void SetElement(int i, const Element &value)
Set element at specified i.
void GetMaximal(const TFastVector< MaxSize, Element > &vector, TFastVector< MaxSize, Element > &result) const
Get vector with maximal elements values.
TFastVector< MaxSize, Element > operator+(const TFastVector< MaxSize, Element > &vector) const
int GetElementsCount() const
Get number of elements.
TFastVector()
Create an uninitialized point.
TFastVector< MaxSize, Element > & operator=(const TFastVector< MaxSize, Element > &vector)
TFastVector< MaxSize, Element > operator*(Element scalar) const
Element m_elements[MaxSize]
void ScaledCumulate(const TFastVector< MaxSize, Element > &vector, Element scale)
Add second vector scaled by specified factor.
bool operator<(const TFastVector< MaxSize, Element > &vector) const
void GetMinimal(const TFastVector< MaxSize, Element > &vector, TFastVector< MaxSize, Element > &result) const
Get vector with minimal elements values.
TFastVector< MaxSize, Element > & operator+=(const TFastVector< MaxSize, Element > &vector)
Element GetDotProduct(const TFastVector< MaxSize, Element > &vector) const
Return dot product of two vectors.
bool operator!=(const TFastVector< MaxSize, Element > &vector) const
bool IsNull(Element tolerance=I_BIG_EPSILON) const
Check if this vector is null.
Element & GetElementRef(int i)
Get reference to element at specified i.
bool EnsureElementsCount(int count, const Element &value=Element())
Ensure, that number of elements vector cannot be smaller that some value.
TFastVector< MaxSize, Element > GetTranslated(const TFastVector< MaxSize, Element > &vector)
Get translated point.
bool Serialize(iser::IArchive &archive)
Serialize this vector to specified archive.
TFastVector(const imath::TVector< Size, Element > &vector)
Definition TFastVector.h:53
const Element & operator[](int i) const
bool operator>(const TFastVector< MaxSize, Element > &vector) const
Element GetDistance2(const TFastVector< MaxSize, Element > &vector) const
Return distance square between two vectors.
void Translate(const TFastVector< MaxSize, Element > &vector)
Translate the point.
TFastVector< MaxSize, Element > operator-(const TFastVector< MaxSize, Element > &vector) const
TFastVector(const TFastVector< MaxSize, Element > &vector)
Copy constructor.
TFastVector(int componentsCount, const Element &value=Element())
Create vector and initialize number of components.
void GetTranslated(const TFastVector< MaxSize, Element > &vector, TFastVector< MaxSize, Element > &result)
/overloaded
Element & operator[](int i)
TFastVector< MaxSize, Element > & operator*=(Element scalar)
Element GetLength() const
Return euclidian length.
TFastVector< MaxSize, Element > operator/(Element scalar) const
Implementation of fixed-size mathematical vector with specified type of elements.
Definition TVector.h:32
Process tag used to group data in archive stream.
Definition CArchiveTag.h:25
@ TT_LEAF
Leaf tag, it can contain only one primitive element.
Definition CArchiveTag.h:51
@ TT_MULTIPLE
Multiple tag containing variable number of child tags.
Definition CArchiveTag.h:45
Represent input/output persistence archive.
Definition IArchive.h:33
virtual bool Process(bool &value)=0
Process primitive type.
virtual bool EndTag(const CArchiveTag &tag)=0
End of archive tag.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begin of archive tag containing set of subelements of the same type.
virtual bool IsChanging() const =0
Check if this archive processing change the object state.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begin of archive tag.
Package with mathematical functions and algebraical primitives.
size_t qHash(const TFastVector< MaxSize, Element > &v, size_t seed=0)

© Witold Gantzke and Kirill Lepskiy