vgl_vector_3d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_vector_3d.h
2 #ifndef vgl_vector_3d_h_
3 #define vgl_vector_3d_h_
4 //:
5 // \file
6 // \brief direction vector in Euclidean 3D space
7 // \author Peter Vanroose
8 // \date 27 June, 2001
9 //
10 // \verbatim
11 // Modifications
12 // 2001-07-05 Peter Vanroose Added orthogonal(); operator* now accepts double
13 // 2009-05-21 Peter Vanroose istream operator>> re-implemented
14 // \endverbatim
15 
16 #include <iosfwd>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 //----------------------------------------------------------------------
22 
23 //: Direction vector in Euclidean 3D space, templated by type of element
24 // (typically float or double). A vgl_vector_3d<T> represents the
25 // difference (or connecting vector) between two vgl_point_3d<T>s.
26 //
27 // Use this class to do arithmetic (adding and scaling) in 3d geometric space.
28 //
29 template <class T>
30 class vgl_vector_3d
31 {
32  public:
33  T x_; // Data is public
34  T y_;
35  T z_;
36  inline T x() const { return x_; }
37  inline T y() const { return y_; }
38  inline T z() const { return z_; }
39 
40  //: Creates the vector (0,0,0) of zero length.
41  inline vgl_vector_3d() : x_(0) , y_(0) , z_(0) {}
42 
43  //: Creates the vector \a (vx,vy,vz).
44  inline vgl_vector_3d(T vx, T vy, T vz) : x_(vx) , y_(vy) , z_(vz) {}
45 
46  //: Creates the vector \a (vx,vy,vz).
47  inline vgl_vector_3d(const T v[3]) : x_(v[0]), y_(v[1]), z_(v[2]) {}
48 
49 #if 0 // The defaults do exactly what they should do...
50  //: Copy constructor
51  inline vgl_vector_3d (vgl_vector_3d<T>const&v):x_(v.x()),y_(v.y()),z_(v.z()){}
52  //: Assignment operator
53  inline vgl_vector_3d<T>& operator=(vgl_vector_3d<T> const& v) {
54  x_=v.x(); y_=v.y(); z_=v.z(); return *this; }
55  //: Destructor
56  inline ~vgl_vector_3d () {}
57 #endif
58 
59  //: Assignment
60  inline void set(T vx, T vy, T vz) { x_=vx; y_=vy; z_=vz; }
61 
62  //: Set \a x, \a y and \a z
63  inline void set (T const v[3]) { x_ = v[0]; y_ = v[1]; z_ = v[2]; }
64 
65  //: Comparison
66  inline bool operator==(vgl_vector_3d<T>const& v) const {
67  return x_==v.x() && y_==v.y() && z_==v.z(); }
68  inline bool operator!=(vgl_vector_3d<T>const& v)const{return !operator==(v);}
69 
70  //: Return the length of this vector.
71  double length() const; // return sqrt( sqr_length() );
72 
73  //: Return the squared length of this vector.
74  inline T sqr_length() const { return x()*x()+y()*y()+z()*z(); }
75 
76 
77  //: One-parameter family of unit vectors that are orthogonal to *this, v(s).
78  // To get two orthogonal vectors call this function twice with s=0 and
79  // s=0.25 for example.
80  // \param s 0<=s<=1, v(0)==v(1)
81  // \note This function is not continuous near z==0. (Under the Hairy Ball
82  // theorem no such smooth function can exist.)
83  // \note This vector need not be normalized but it should have non-zero length.
84  // \deprecated Use global function orthogonal_vectors(vgl_vector_3d<T > const& a, double s) instead.
85  vgl_vector_3d<T> orthogonal_vectors(double s) const;
86 
87  //: Read from stream, possibly with formatting
88  // Either just reads three blank-separated numbers,
89  // or reads three comma-separated numbers,
90  // or reads three numbers in parenthesized form "(123, 321, 567)"
91  // \relatesalso vgl_point_3d
92  std::istream& read(std::istream& is);
93 };
94 
95 #define v vgl_vector_3d<T>
96 
97 // +-+-+ vector_3d simple I/O +-+-+
98 
99 //: Write "<vgl_vector_3d x,y,z> " to stream
100 // \relatesalso vgl_vector_3d
101 template <class T> std::ostream& operator<<(std::ostream& s, v const& p);
102 
103 //: Read from stream, possibly with formatting
104 // Either just reads three blank-separated numbers,
105 // or reads three comma-separated numbers,
106 // or reads three numbers in parenthesized form "(123, 321, 567)"
107 // \relatesalso vgl_vector_3d
108 template <class T> std::istream& operator>>(std::istream& s, v& p);
109 
110 
111 // +-+-+ vector_3d geometry and algebra +-+-+
112 
113 //: Return the length of a vector.
114 // \relatesalso vgl_vector_3d
115 template <class T> inline double length(v const& a) { return a.length(); }
116 
117 //: Return the squared length of a vector.
118 // \relatesalso vgl_vector_3d
119 template <class T> inline T sqr_length(v const& a) { return a.sqr_length(); }
120 
121 //: c=a+b: add two vectors.
122 // \relatesalso vgl_vector_3d
123 template <class T> inline v operator+(v const& a, v const& b) { return v(a.x()+b.x(), a.y()+b.y(), a.z()+b.z()); }
124 
125 //: c=a-b: subtract two vectors.
126 // \relatesalso vgl_vector_3d
127 template <class T> inline v operator-(v const& a, v const& b) { return v(a.x()-b.x(), a.y()-b.y(), a.z()-b.z()); }
128 
129 //: a+=b: add b to a and return a.
130 // \relatesalso vgl_vector_3d
131 template <class T> inline v& operator+=(v& a, v const& b) { a.x_+=b.x_; a.y_+=b.y_; a.z_+=b.z_; return a; }
132 
133 //: a-=b: subtract b from a and return a.
134 // \relatesalso vgl_vector_3d
135 template <class T> inline v& operator-=(v& a, v const& b) { a.x_-=b.x_; a.y_-=b.y_; a.z_-=b.z_; return a; }
136 
137 //: +b: unary plus operator (no-op).
138 // \relatesalso vgl_vector_3d
139 template <class T> inline v operator+(v const& b) { return b; }
140 
141 //: -a: unary minus operator (additive inverse).
142 // \relatesalso vgl_vector_3d
143 template <class T> inline v operator-(v const& b) { return v(-b.x(), -b.y(), -b.z()); }
144 
145 //: c=f*b: return a scaled version of the vector.
146 // \relatesalso vgl_vector_3d
147 template <class T> inline v operator*(double s, v const& b) { return v(T(s*b.x()), T(s*b.y()), T(s*b.z())); }
148 
149 //: c=a*f: return a scaled version of the vector.
150 // \relatesalso vgl_vector_3d
151 template <class T> inline v operator*(v const& a, double s) { return v(T(a.x()*s), T(a.y()*s), T(a.z()*s)); }
152 
153 //: c=b/f: return an inversely scaled version of the vector (scale must be nonzero).
154 // Note that the argument type is double, not T, to avoid rounding errors
155 // when type T has no multiplicative inverses (like T=int).
156 // \relatesalso vgl_vector_3d
157 template <class T> inline v operator/(v const& a, double s) { return v(T(a.x()/s), T(a.y()/s), T(a.z()/s)); }
158 
159 //: a*=f: scale the vector.
160 // \relatesalso vgl_vector_3d
161 template <class T> inline v& operator*=(v& a, double s) { a.set(T(a.x()*s), T(a.y()*s), T(a.z()*s)); return a; }
162 
163 //: a/=f: inversely scale the vector (scale must be nonzero).
164 // \relatesalso vgl_vector_3d
165 template <class T> inline v& operator/=(v& a, double s) { a.set(T(a.x()/s), T(a.y()/s), T(a.z()/s)); return a; }
166 
167 //: dot product or inner product of two vectors.
168 // \relatesalso vgl_vector_3d
169 template <class T> inline T dot_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y()+a.z()*b.z(); }
170 
171 //: dot product or inner product of two vectors.
172 // \relatesalso vgl_vector_3d
173 template <class T> inline T inner_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y()+a.z()*b.z(); }
174 
175 //: cross product of two vectors (is orthogonal to both)
176 // \relatesalso vgl_vector_3d
177 template <class T> inline v cross_product(v const& a, v const& b)
178 { return v(a.y()*b.z()-a.z()*b.y(), a.z()*b.x()-a.x()*b.z(), a.x()*b.y()-a.y()*b.x()); }
179 
180 //: cosine of the angle between two vectors.
181 // \relatesalso vgl_vector_3d
182 template <class T> inline double cos_angle(v const& a, v const& b) { return inner_product(a,b)/(a.length()*b.length()); }
183 
184 //: smallest angle between two vectors (in radians, between 0 and Pi).
185 // \relatesalso vgl_vector_3d
186 template <class T> double angle(v const& a, v const& b); // return acos(cos_angle(a,b));
187 
188 //: are two vectors orthogonal, i.e., is their dot product zero?
189 // If the third argument is specified, it is taken as the "tolerance", i.e.
190 // in that case this function returns true if the vectors are almost orthogonal.
191 // \relatesalso vgl_vector_3d
192 template <class T> bool orthogonal(v const& a, v const& b, double eps=0.0);
193 
194 //: are two vectors parallel, i.e., is one a scalar multiple of the other?
195 // If the third argument is specified, it is taken as the "tolerance", i.e.
196 // in that case this function returns true if the vectors are almost parallel.
197 // \relatesalso vgl_vector_3d
198 template <class T> bool parallel(v const& a, v const& b, double eps=0.0);
199 
200 //: f=a/b: return the ratio of two vectors, if they are parallel.
201 // (If not, return a "least squares" approximation.)
202 // Note that the return type is double, not T, since the ratio of e.g.
203 // two vgl_vector_3d<int> need not be an int.
204 // \relatesalso vgl_vector_3d
205 template <class T> inline double operator/(v const& a, v const& b)
206 { return dot_product(a,b)/(double)dot_product(b,b); }
207 
208 //: Normalise by dividing through by the length, thus returning a length 1 vector.
209 // If a is zero length, return (0,0).
210 // \relatesalso vgl_vector_3d
211 template <class T> inline v& normalize(v& a) { double l=a.length(); return l?a/=l:a; }
212 
213 //: Return a normalised version of a.
214 // If a is zero length, return (0,0).
215 // \relatesalso vgl_vector_3d
216 template <class T> inline v normalized(v const& a) { double l=a.length(); return l?a/l:a; }
217 
218 //: One-parameter family of unit vectors that are orthogonal to \a a, v(s).
219 // To get two orthogonal vectors call this function twice with s=0 and
220 // s=0.25 for example.
221 // \param s 0<=s<=1, v(0)==v(1)
222 // \note This function is not continuous near z==0. (Under the Hairy Ball
223 // theorem no such smooth function can exist.)
224 // \note This vector need not be normalized but it should have non-zero length.
225 template <class T> v orthogonal_vectors(v const& a, double s);
226 
227 #undef v
228 
229 #define VGL_VECTOR_3D_INSTANTIATE(T) extern "please include vgl/vgl_vector_3d.hxx first"
230 
231 #endif // vgl_vector_3d_h_
v normalized(v const &a)
Return a normalised version of a.
vgl_vector_3d()
Creates the vector (0,0,0) of zero length.
Definition: vgl_vector_3d.h:41
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
T inner_product(v const &a, v const &b)
dot product or inner product of two vectors.
v & operator/=(v &a, double s)
a/=f: inversely scale the vector (scale must be nonzero).
v orthogonal_vectors(v const &a, double s)
One-parameter family of unit vectors that are orthogonal to a, v(s).
v & normalize(v &a)
Normalise by dividing through by the length, thus returning a length 1 vector.
vgl_homg_point_1d< T > & operator-=(vgl_homg_point_1d< T > &p, T v)
Subtracting a number from a point is the same as adding the inverse number.
v & operator *=(v &a, double s)
a*=f: scale the vector.
vgl_homg_point_1d< T > & operator+=(vgl_homg_point_1d< T > &p, T v)
Adding a number to a 1-D point translates that point.
bool orthogonal(v const &a, v const &b, double eps=0.0)
are two vectors orthogonal, i.e., is their dot product zero?.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_vector_3d(T vx, T vy, T vz)
Creates the vector (vx,vy,vz).
Definition: vgl_vector_3d.h:44
double length(v const &a)
Return the length of a vector.
Definition: vgl_vector_2d.h:94
#define v
Definition: vgl_vector_3d.h:95
vgl_vector_3d< T > orthogonal_vectors(double s) const
One-parameter family of unit vectors that are orthogonal to *this, v(s).
double length() const
Return the length of this vector.
T cross_product(v const &a, v const &b)
cross product of two vectors (area of enclosed parallellogram).
vgl_vector_3d(const T v[3])
Creates the vector (vx,vy,vz).
Definition: vgl_vector_3d.h:47
v operator/(v const &a, double s)
c=b/f: return an inversely scaled version of the vector (scale must be nonzero).
T y() const
Definition: vgl_vector_3d.h:37
vgl_homg_point_1d< T > operator+(vgl_homg_point_1d< T > const &p, T v)
Adding a number to a 1-D point translates that point.
T x() const
Definition: vgl_vector_3d.h:36
T sqr_length() const
Return the squared length of this vector.
Definition: vgl_vector_3d.h:74
T z() const
Definition: vgl_vector_3d.h:38
bool operator==(vgl_vector_3d< T >const &v) const
Comparison.
Definition: vgl_vector_3d.h:66
Direction vector in Euclidean 3D space, templated by type of element.
Definition: vgl_fwd.h:13
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
T sqr_length(v const &a)
Return the squared length of a vector.
Definition: vgl_vector_2d.h:98
void set(T vx, T vy, T vz)
Assignment.
Definition: vgl_vector_3d.h:60
double angle(v const &a, v const &b)
smallest angle between two vectors (in radians, between 0 and Pi).
#define l
std::istream & read(std::istream &is)
Read from stream, possibly with formatting.
vgl_homg_point_1d< T > operator *(vnl_matrix_fixed< T, 2, 2 > const &m, vgl_homg_point_1d< T > const &p)
Transform a point through a 2x2 projective transformation matrix.
void set(T const v[3])
Set x, y and z.
Definition: vgl_vector_3d.h:63
bool parallel(v const &a, v const &b, double eps=0.0)
are two vectors parallel, i.e., is one a scalar multiple of the other?.
bool operator!=(vgl_vector_3d< T >const &v) const
Definition: vgl_vector_3d.h:68
double cos_angle(v const &a, v const &b)
cosine of the angle between two vectors.
T operator-(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2)
The difference of two points is the distance between the two.