BALL  1.4.79
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
vector3.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_MATHS_VECTOR3_H
6 #define BALL_MATHS_VECTOR3_H
7 
8 #ifndef BALL_COMMON_EXCEPTION_H
9 # include <BALL/COMMON/exception.h>
10 #endif
11 
12 #ifndef BALL_CONCEPT_PERSISTENCEMANAGER_H
14 #endif
15 
16 #ifndef BALL_MATHS_ANGLE_H
17 # include <BALL/MATHS/angle.h>
18 #endif
19 
20 #ifndef BALL_MATHS_COMMON_H
21 # include <BALL/MATHS/common.h>
22 #endif
23 
24 #ifdef BALL_HAS_IEEEFP_H
25 # include <ieeefp.h>
26 #endif
27 
28 
29 namespace BALL
30 {
36 
37  template <typename T>
38  class TVector3;
39 
43 
47  template <typename T>
49  TVector3<T> operator * (const T& a, const TVector3<T>& b);
50 
55  template <typename T>
56  std::istream& operator >> (std::istream& s, TVector3<T>& vector);
57 
62  template <typename T>
63  std::ostream& operator << (std::ostream& s, const TVector3<T>& vector);
64 
66 
69  template <typename T>
70  class TVector3
71  {
72  public:
73 
77 
82  TVector3();
83 
90  explicit TVector3(const T* ptr);
91 
97  explicit TVector3(const T& value);
98 
102  template<typename T2>
103  explicit TVector3(const TVector3<T2>& vec);
104 
111  TVector3(const T& vx, const T& vy, const T& vz);
112 
117  TVector3(const TVector3& vector);
118 
128  TVector3(const T& r, const TAngle<T>& phi, const TAngle<T>& theta);
129 
134  ~TVector3();
135 
139  void clear();
140 
142 
146 
153  void set(const T* ptr);
154 
159  void set(const T& value);
160 
166  void set(const T& vx, const T& vy, const T& vz);
167 
171  void set(const TVector3& vector);
172 
185  void set(const T& r, const TAngle<T>& phi, const TAngle<T>& theta);
186 
191  TVector3& operator = (const TVector3& v);
192 
197  TVector3& operator = (T value);
198 
204  TVector3& operator = (const T* ptr);
205 
212  void get(T* ptr) const;
213 
219  void get(T& x, T& y, T& z) const;
220 
225  void get(TVector3& vector) const;
226 
234  void get(T& r, TAngle<T>& phi, TAngle<T>& theta) const;
235 
239  void swap(TVector3& vector);
240 
246  T getLength() const;
247 
253  T getSquareLength() const;
254 
261  TVector3& normalize();
262 
267  TVector3& negate();
268 
271  static const TVector3& getZero();
272 
276  static const TVector3& getUnit();
277 
281  T& operator [] (Position position);
282 
286  const T& operator [] (Position position) const;
288 
292 
295  const TVector3& operator + () const;
296 
299  TVector3 operator - () const;
300 
303  TVector3 operator + (const TVector3& b) const;
304 
307  TVector3 operator - (const TVector3& b) const;
308 
314  TVector3& operator += (const TVector3& vector);
315 
320  TVector3& operator -= (const TVector3& vector);
321 
327  TVector3 operator * (const T& scalar) const;
328 
334  TVector3& operator *= (const T& scalar);
335 
342  TVector3 operator / (const T& lambda) const;
343 
349  TVector3& operator /= (const T& lambda);
350 
354  T operator * (const TVector3& vector) const;
355 
359  TVector3 operator % (const TVector3& vector) const;
360 
364  TVector3& operator %= (const TVector3& vector);
365 
367 
371 
374  T getDistance(const TVector3& vector) const;
375 
378  T getSquareDistance(const TVector3& vector) const;
379 
384  TAngle<T> getAngle(const TVector3& vector) const;
385 
389  TVector3 getOrthogonalProjection(const TVector3& direction) const;
390 
398  (const TVector3& a, const TVector3& b, const TVector3& c);
399 
407  static T getTripleProduct (const TVector3<T>& a, const TVector3<T>& b, const TVector3<T>& c);
408 
410 
414 
420  bool operator == (const TVector3& vector) const;
421 
427  bool operator != (const TVector3& vector) const;
428 
430  bool operator < (const TVector3& vector) const;
431 
432 
437  bool isZero() const;
438 
441  bool isOrthogonalTo(const TVector3& vector) const;
442 
444 
445 
449 
452  void write(PersistenceManager& pm) const;
453 
456  bool read(PersistenceManager& pm);
457 
459 
463 
470  void dump(std::ostream& s = std::cout, Size depth = 0) const;
471 
476  bool isValid() const;
477 
479 
480 
486 
489  T x;
490 
493  T y;
494 
497  T z;
499 
500  private:
501 
502  TAngle<T> getAngle_(const T& a, const T& b) const
503  {
504  TAngle<T> angle;
505 
506  if (Maths::isNotZero(a))
507  {
508  angle = atan(b / a);
509  }
510  else
511  {
512  angle = BALL_SGN(b) * Constants::PI / 2;
513  }
514 
515  if (Maths::isLess(a, 0))
516  {
517  angle += Constants::PI;
518  }
519 
520  if (Maths::isLess(angle.value, 0))
521  {
522  return (Angle)(angle.value += 2.0 * Constants::PI);
523  }
524  else
525  {
526  return angle;
527  }
528  }
529  };
531 
532  template <typename T>
535  : x(0),
536  y(0),
537  z(0)
538  {
539  }
540 
541  template <typename T>
543  TVector3<T>::TVector3(const T* ptr)
544  {
545  if (ptr == 0)
546  {
547  throw Exception::NullPointer(__FILE__, __LINE__);
548  }
549 
550  x = *ptr++;
551  y = *ptr++;
552  z = *ptr;
553  }
554 
555  template <typename T>
557  TVector3<T>::TVector3(const T& value)
558  : x(value),
559  y(value),
560  z(value)
561  {
562  }
563 
564  template <typename T> template <typename T2>
567  : x((T)vec.x),
568  y((T)vec.y),
569  z((T)vec.z)
570  {
571  }
572 
573  template <typename T>
575  TVector3<T>::TVector3(const T& vx, const T& vy, const T& vz)
576  : x(vx),
577  y(vy),
578  z(vz)
579  {
580  }
581 
582  template <typename T>
585  : x(vector.x),
586  y(vector.y),
587  z(vector.z)
588  {
589  }
590 
591  template <typename T>
593  TVector3<T>::TVector3(const T& r, const TAngle<T>& phi, const TAngle<T>& theta)
594  : x(r * cos(phi) * sin(theta)),
595  y(r * sin(phi) * sin(theta)),
596  z(r * cos(theta))
597  {
598  }
599 
600  template <typename T>
603  {
604  }
605 
606  template <typename T>
609  {
610  x = y = z = (T)0;
611  }
612 
613  template <typename T>
614  BALL_INLINE
615  void TVector3<T>::set(const T* ptr)
616  {
617  if (ptr == 0)
618  throw Exception::NullPointer(__FILE__, __LINE__);
619 
620  x = *ptr++;
621  y = *ptr++;
622  z = *ptr;
623  }
624 
625  template <typename T>
626  BALL_INLINE
627  void TVector3<T>::set(const T& value)
628  {
629  x = value;
630  y = value;
631  z = value;
632  }
633 
634  template <typename T>
635  BALL_INLINE
636  void TVector3<T>::set(const T& vx, const T& vy, const T& vz)
637  {
638  x = vx;
639  y = vy;
640  z = vz;
641  }
642 
643  template <typename T>
644  BALL_INLINE
645  void TVector3<T>::set(const TVector3<T>& vector)
646  {
647  x = vector.x;
648  y = vector.y;
649  z = vector.z;
650  }
651 
652  template <typename T>
654  void TVector3<T>::set(const T& r, const TAngle<T> &phi, const TAngle<T> &theta)
655  {
656  x = r * cos(phi) * sin(theta);
657  y = r * sin(phi) * sin(theta);
658  z = r * cos(theta);
659  }
660 
661  template <typename T>
664  {
665  if (ptr == 0)
666  {
667  throw Exception::NullPointer(__FILE__, __LINE__);
668  }
669 
670  x = *ptr++;
671  y = *ptr++;
672  z = *ptr;
673 
674  return *this;
675  }
676 
677  template <typename T>
678  BALL_INLINE
680  {
681  x = vector.x;
682  y = vector.y;
683  z = vector.z;
684 
685  return *this;
686  }
687 
688  template <typename T>
689  BALL_INLINE
691  {
692  x = y = z = value;
693 
694  return *this;
695  }
696 
697  template <typename T>
698  BALL_INLINE
699  void TVector3<T>::get(T* ptr) const
700  {
701  if (ptr == 0)
702  {
703  throw Exception::NullPointer(__FILE__, __LINE__);
704  }
705 
706  *ptr++ = x;
707  *ptr++ = y;
708  *ptr = z;
709  }
710 
711  template <typename T>
712  BALL_INLINE
713  void TVector3<T>::get(T& new_x, T& new_y, T& new_z) const
714  {
715  new_x = x;
716  new_y = y;
717  new_z = z;
718  }
719 
720  template <typename T>
721  BALL_INLINE
722  void TVector3<T>::get(TVector3<T>& vector) const
723  {
724  vector.x = x;
725  vector.y = y;
726  vector.z = z;
727  }
728 
729  template <typename T>
730  BALL_INLINE
731  void TVector3<T>::get(T& r, TAngle<T>& phi, TAngle<T>& theta) const
732  {
733  r = sqrt(x * x + y * y + z * z);
734  phi = (Angle)getAngle_(x, y);
735  theta = getAngle_(z, sqrt(x * x + y * y));
736  }
737 
738  template <typename T>
741  {
742  T temp = x;
743  x = vector.x;
744  vector.x = temp;
745 
746  temp = y;
747  y = vector.y;
748  vector.y = temp;
749 
750  temp = z;
751  z = vector.z;
752  vector.z = temp;
753  }
754 
755  template <typename T>
756  BALL_INLINE
758  {
759  return (T)sqrt(x * x + y * y + z * z);
760  }
761 
762  template <typename T>
763  BALL_INLINE
765  {
766  return (x * x + y * y + z * z);
767  }
768 
769  template <typename T>
771  {
772  T len = sqrt(x * x + y * y + z * z);
773 
774  if (Maths::isZero(len))
775  {
776  throw Exception::DivisionByZero(__FILE__, __LINE__);
777  }
778 
779  x /= len;
780  y /= len;
781  z /= len;
782 
783  return *this;
784  }
785 
786  template <typename T>
789  {
790  x *= -1;
791  y *= -1;
792  z *= -1;
793  return *this;
794  }
795 
796  template <typename T>
797  BALL_INLINE
799  {
800  static TVector3<T> null_vector(0, 0, 0);
801  return null_vector;
802  }
803 
804  template <typename T>
805  BALL_INLINE
807  {
808  static TVector3<T> unit_vector(1, 1, 1);
809  return unit_vector;
810  }
811 
812  template <typename T>
813  BALL_INLINE
815  {
816  if (position > 2)
817  {
818  throw Exception::IndexOverflow(__FILE__, __LINE__, position);
819  }
820  switch (position)
821  {
822  case 0: return x;
823  case 1: return y;
824  case 2:
825  default:
826  return z;
827  }
828  }
829 
830  template <typename T>
831  BALL_INLINE
832  const T& TVector3<T>::operator [] (Position position) const
833  {
834  if (position > 2)
835  {
836  throw Exception::IndexOverflow(__FILE__, __LINE__);
837  }
838  switch (position)
839  {
840  case 0: return x;
841  case 1: return y;
842  case 2:
843  default:
844  return z;
845  }
846  }
847 
848  template <typename T>
851  {
852  return *this;
853  }
854 
855  template <typename T>
858  {
859  return TVector3<T>(-x, -y, -z);
860  }
861 
862  template <typename T>
863  BALL_INLINE
865  {
866  x += vector.x;
867  y += vector.y;
868  z += vector.z;
869 
870  return *this;
871  }
872 
873  template <typename T>
874  BALL_INLINE
876  {
877  x -= vector.x;
878  y -= vector.y;
879  z -= vector.z;
880 
881  return *this;
882  }
883 
884  template <typename T>
885  BALL_INLINE
886  TVector3<T> TVector3<T>::operator * (const T& scalar) const
887  {
888  return TVector3<T>(x * scalar, y * scalar, z * scalar);
889  }
890 
891  template <typename T>
892  BALL_INLINE
894  {
895  x *= scalar;
896  y *= scalar;
897  z *= scalar;
898 
899  return *this;
900  }
901 
902  template <typename T>
903  TVector3<T> TVector3<T>::operator / (const T& lambda) const
904  {
905  if (lambda == (T)0)
906  {
907  throw Exception::DivisionByZero(__FILE__, __LINE__);
908  }
909  return TVector3<T>(x / lambda, y / lambda, z / lambda);
910  }
911 
912  template <typename T>
914  {
915  if (lambda == (T)0)
916  {
917  throw Exception::DivisionByZero(__FILE__, __LINE__);
918  }
919  x /= lambda;
920  y /= lambda;
921  z /= lambda;
922 
923  return *this;
924  }
925 
926  template <typename T>
927  BALL_INLINE
928  T TVector3<T>::operator * (const TVector3<T>& vector) const
929  {
930  return (x * vector.x + y * vector.y + z * vector.z);
931  }
932 
933  template <typename T>
935  {
936  return TVector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
937  }
938 
939  template <typename T>
940  BALL_INLINE
942  {
943  set(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
944  return *this;
945  }
946 
947  template <typename T>
948  BALL_INLINE
950  {
951  T dx = x - v.x;
952  T dy = y - v.y;
953  T dz = z - v.z;
954 
955  return (T)sqrt(dx * dx + dy * dy + dz * dz);
956  }
957 
958  template <typename T>
959  BALL_INLINE T
961  {
962  T dx = x - v.x;
963  T dy = y - v.y;
964  T dz = z - v.z;
965 
966  return (dx * dx + dy * dy + dz * dz);
967  }
968 
969  template <typename T>
970  BALL_INLINE
972  {
973  T length_product = getSquareLength() * vector.getSquareLength();
974 
975  if (length_product == (T)0)
976  {
977  throw Exception::DivisionByZero(__FILE__, __LINE__);
978  }
979 
980  T acos_arg = ((*this) * vector) / sqrt(length_product);
981 
982  // ensure that the argument of acos is in the correct range
983  // (might happen if the angle between the two vectors is
984  // very close to zero)
985  if (fabs(acos_arg) > 1.0)
986  {
987  return (TAngle<T>)0.0;
988  }
989 
990  return (TAngle<T>)acos(acos_arg);
991  }
992 
993  template <typename T>
994  BALL_INLINE
996  {
997  return ((direction * (*this)) / (direction * direction) * direction);
998  }
999 
1000  template <typename T>
1002  (const TVector3<T> &a, const TVector3<T> &b, const TVector3<T> &c)
1003  {
1004  TVector3 diff1(b.x - a.x, b.y - a.y, b.z - a.z);
1005  TVector3 diff2(b.x - c.x, b.y - c.y, b.z - c.z);
1006 
1007  return TVector3
1008  (diff1.y * diff2.z - diff1.z * diff2.y,
1009  diff1.z * diff2.x - diff1.x * diff2.z,
1010  diff1.x * diff2.y - diff1.y * diff2.x);
1011  }
1012 
1013  template <typename T>
1014  BALL_INLINE
1016  (const TVector3<T>& a,
1017  const TVector3<T>& b,
1018  const TVector3<T>& c)
1019  {
1020  return ( a.x * (b.y * c.z - b.z * c.y)
1021  + a.y * (b.z * c.x - b.x * c.z)
1022  + a.z * (b.x * c.y - b.y * c.x));
1023  }
1024 
1025  template <typename T>
1026  BALL_INLINE
1028  {
1029  return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y) && Maths::isEqual(z, v.z));
1030  }
1031 
1032  template <typename T>
1033  BALL_INLINE
1035  {
1036  return (x < v.x || y < v.y || z < v.z);
1037  }
1038 
1039 
1040  template <typename T>
1041  BALL_INLINE
1043  {
1044  return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y) || Maths::isNotEqual(z, v.z));
1045  }
1046 
1047  template <typename T>
1048  BALL_INLINE
1050  {
1051  return Maths::isZero((*this) * v);
1052  }
1053 
1054  template <typename T>
1055  BALL_INLINE
1057  {
1058  return true;
1059  }
1060 
1061  template <typename T>
1062  BALL_INLINE
1063  bool TVector3<T>::isZero() const
1064  {
1065  return (Maths::isZero(x) && Maths::isZero(y) && Maths::isZero(z));
1066  }
1067 
1068  template <typename T>
1069  void TVector3<T>::dump(std::ostream& s, Size depth) const
1070  {
1072 
1073  BALL_DUMP_HEADER(s, this, this);
1074 
1075  BALL_DUMP_DEPTH(s, depth);
1076  s << " (x = " << x << ", y = " << y << ", z = " << z << ")" << std::endl;
1077 
1079  }
1080 
1085 
1086  template <typename T>
1087  BALL_INLINE
1089  {
1090  return TVector3<T>(x + b.x, y + b.y, z + b.z);
1091  }
1092 
1093  template <typename T>
1094  BALL_INLINE
1095  TVector3<T> TVector3<T>::operator - (const TVector3<T>& b) const
1096  {
1097  return TVector3<T>(x - b.x, y - b.y, z - b.z);
1098  }
1099 
1100  template <typename T>
1102  {
1103  pm.writePrimitive(x, "x");
1104  pm.writePrimitive(y, "y");
1105  pm.writePrimitive(z, "z");
1106  }
1107 
1108  template <typename T>
1110  {
1111  pm.readPrimitive(x, "x");
1112  pm.readPrimitive(y, "y");
1113  pm.readPrimitive(z, "z");
1114 
1115  return true;
1116  }
1117 
1118 
1119  template <typename T>
1120  BALL_INLINE
1121  TVector3<T> operator * (const T& scalar, const TVector3<T>& vector)
1122  {
1123  return TVector3<T>(scalar * vector.x, scalar * vector.y, scalar * vector.z);
1124  }
1125 
1126  template <typename T>
1127  std::istream& operator >> (std::istream& s, TVector3<T>& v)
1128  {
1129  char c;
1130  s >> c >> v.x >> v.y >> v.z >> c;
1131 
1132  return s;
1133  }
1134 
1135  template <typename T>
1136  std::ostream& operator << (std::ostream& s, const TVector3<T>& v)
1137  {
1138  s << "(" << v.x << ' ' << v.y << ' ' << v.z << ')';
1139 
1140  return s;
1141  }
1142 // required for visual studio
1143 #ifdef BALL_COMPILER_MSVC
1144 #include <vector>
1145 #ifdef BALL_HAS_EXTERN_TEMPLATES
1146 extern template class BALL_EXPORT std::vector<Vector3>;
1147 #elif
1148 template class BALL_EXPORT std::vector<Vector3>;
1149 #endif
1150 #endif
1151 
1152 #ifdef BALL_HAS_EXTERN_TEMPLATES
1153 extern template class BALL_EXPORT TVector3<float>;
1154 #endif
1155 
1156 }// namespace BALL
1157 
1158 #endif // BALL_MATHS_VECTOR3_H
TVector3 & normalize()
Definition: vector3.h:770
TVector3 & operator/=(const T &lambda)
Definition: vector3.h:913
static T getTripleProduct(const TVector3< T > &a, const TVector3< T > &b, const TVector3< T > &c)
Definition: vector3.h:1016
bool isEqual(const T1 &a, const T2 &b)
Definition: MATHS/common.h:219
TVector3 & operator*=(const T &scalar)
Definition: vector3.h:893
T getSquareDistance(const TVector3 &vector) const
Definition: vector3.h:960
static TVector3 getPerpendicularNormalization(const TVector3 &a, const TVector3 &b, const TVector3 &c)
Definition: vector3.h:1002
void get(T *ptr) const
Definition: vector3.h:699
const TVector3 & operator+() const
Definition: vector3.h:850
std::istream & operator>>(std::istream &is, TRegularData1D< ValueType > &grid)
Input operator.
TVector3 operator-() const
Definition: vector3.h:857
T getLength() const
Definition: vector3.h:757
bool isNotZero(const T &t)
Definition: MATHS/common.h:207
bool isValid() const
Definition: vector3.h:1056
void clear()
Definition: vector3.h:608
static const TVector3 & getUnit()
Definition: vector3.h:806
bool isZero(const T &t)
Definition: MATHS/common.h:196
void write(PersistenceManager &pm) const
Definition: vector3.h:1101
bool readPrimitive(T &t, const char *name)
void dump(std::ostream &s=std::cout, Size depth=0) const
Definition: vector3.h:1069
static const TVector3 & getZero()
Definition: vector3.h:798
void writePrimitive(const T &t, const char *name)
TVector3 & operator=(const TVector3 &v)
BALL_EXTERN_VARIABLE const double c
Definition: constants.h:149
bool isZero() const
Definition: vector3.h:1063
#define BALL_INLINE
Definition: debug.h:15
bool read(PersistenceManager &pm)
Definition: vector3.h:1109
TVector3 & operator-=(const TVector3 &vector)
Definition: vector3.h:875
T getSquareLength() const
Definition: vector3.h:764
#define BALL_DUMP_HEADER(os, cl, ob)
Definition: macros.h:86
bool operator==(const TVector3 &vector) const
Definition: vector3.h:1027
TVector3< float > Vector3
Definition: vector3.h:1084
TVector3 operator%(const TVector3 &vector) const
Definition: vector3.h:934
TVector3 & operator+=(const TVector3 &vector)
Definition: vector3.h:864
void swap(TVector3 &vector)
Definition: vector3.h:740
bool isNotEqual(const T1 &a, const T2 &b)
Definition: MATHS/common.h:231
TAngle< float > Angle
Definition: angle.h:705
TVector3 operator/(const T &lambda) const
Definition: vector3.h:903
bool isLess(const T1 &a, const T2 &b)
Definition: MATHS/common.h:243
TAngle< T > getAngle(const TVector3 &vector) const
Definition: vector3.h:971
TVector3 & negate()
Definition: vector3.h:788
T getDistance(const TVector3 &vector) const
Definition: vector3.h:949
#define BALL_SGN(x)
Definition: macros.h:28
BALL_INLINE TAngle< T > operator*(const T &val, const TAngle< T > &angle)
Definition: angle.h:712
#define BALL_DUMP_STREAM_PREFIX(os)
Definition: macros.h:84
BALL_EXTERN_VARIABLE const double PI
PI.
Definition: constants.h:35
T & operator[](Position position)
Definition: vector3.h:814
bool operator<(const TVector3 &vector) const
Needed for MSVC.
Definition: vector3.h:1034
TVector3 getOrthogonalProjection(const TVector3 &direction) const
Definition: vector3.h:995
#define BALL_DUMP_STREAM_SUFFIX(os)
Definition: macros.h:88
void set(const T *ptr)
Definition: vector3.h:615
#define BALL_DUMP_DEPTH(os, depth)
Definition: macros.h:83
bool isOrthogonalTo(const TVector3 &vector) const
Definition: vector3.h:1049
TVector3 & operator%=(const TVector3 &vector)
Definition: vector3.h:941
bool operator!=(const TVector3 &vector) const
Definition: vector3.h:1042
#define BALL_EXPORT
Definition: COMMON/global.h:50
TVector3 operator*(const T &scalar) const
Definition: vector3.h:886