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

© 2007-2017 Witold Gantzke and Kirill Lepskiy