vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gm_vec3.h
Go to the documentation of this file.
1 // gmVector3.h - 3 element vector class
2 //
3 // libgm++: Graphics Math Library
4 // Ferdi Scheepers and Stephen F May
5 // 15 June 1994
6 // ----------------------------------
7 // modified: October 2002
8 // Pavel Kolcarek, kolcarek@fi.muni.cz
9 //
10 
11 #ifndef GM_VECTOR3_H
12 #define GM_VECTOR3_H
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <assert.h>
17 #include <gm_utils.h>
18 #include <iostream>
19 
20 using namespace std;
21 
22 class gmVector3 {
23 
24 protected:
25  double v_[3];
26 
27 public:
28  gmVector3();
29  gmVector3(const gmVector3&);
30  gmVector3(double, double, double);
31 
32  // array access
33 
34  double& operator [](int);
35  const double& operator [](int) const;
36 
37  // assignment
38 
39  gmVector3& assign(double, double, double);
40  gmVector3& operator =(const gmVector3&);
41 
42  // math operators
43 
44  gmVector3& operator +=(const gmVector3&);
45  gmVector3& operator -=(const gmVector3&);
46  gmVector3& operator *=(double);
47  gmVector3& operator /=(double);
48 
49  gmVector3 operator +(const gmVector3&) const;
50  gmVector3 operator -(const gmVector3&) const;
51  gmVector3 operator -() const;
52  gmVector3 operator *(double) const;
53  gmVector3 operator /(double) const;
54 
55 friend gmVector3 operator *(double, const gmVector3&);
56 
57  bool operator ==(const gmVector3&) const;
58  bool operator !=(const gmVector3&) const;
59 
60  // operations
61 
62  gmVector3& clamp(double, double);
63  double length() const;
64  double lengthSquared() const;
65  gmVector3& normalize();
66  bool isZero();
67 
68  void copyTo(float [3]) const;
69  void copyTo(double [3]) const;
70  void float2double(const float *v);
71  void double2float(const double *v);
72 
73 friend gmVector3 cross(const gmVector3&, const gmVector3&);
74 friend double distance(const gmVector3&, const gmVector3&);
75 friend double distanceSquared(const gmVector3&, const gmVector3&);
76 friend double dot(const gmVector3&, const gmVector3&);
77 friend gmVector3 lerp(double, const gmVector3&, const gmVector3&);
78 
79  // useful functions
80 
81 friend double plane_intersect(const gmVector3&, const gmVector3&,
82  const gmVector3&, const gmVector3&);
83 friend double line_distance(const gmVector3&, const gmVector3&,
84  const gmVector3&, const gmVector3&);
85 friend double plane_distance(const gmVector3&, const gmVector3&, const gmVector3&);
86 
87 // todo
88 //
89 //friend cos_angle();
90 //friend angle(); // return angle of two vectors
91 
92  // output
93 
94 friend ostream & operator << ( ostream &, const gmVector3 & );
95 };
96 
97 // CONSTRUCTORS
98 
100 {
101  v_[0] = v_[1] = v_[2] = 0;
102 }
103 
105 {
106  v_[0] = v.v_[0]; v_[1] = v.v_[1]; v_[2] = v.v_[2];
107 }
108 
109 inline gmVector3::gmVector3(double x, double y, double z)
110 {
111  v_[0] = x; v_[1] = y; v_[2] = z;
112 }
113 
114 // ARRAY ACCESS
115 
116 inline double& gmVector3::operator [](int i)
117 {
118  assert(i == 0 || i == 1 || i == 2);
119  return v_[i];
120 }
121 
122 inline const double& gmVector3::operator [](int i) const
123 {
124  assert(i == 0 || i == 1 || i == 2);
125  return v_[i];
126 }
127 
128 // ASSIGNMENT
129 
130 inline gmVector3& gmVector3::assign(double x, double y, double z)
131 {
132  v_[0] = x; v_[1] = y; v_[2] = z;
133  return *this;
134 }
135 
137 {
138  v_[0] = v[0]; v_[1] = v[1]; v_[2] = v[2];
139  return *this;
140 }
141 
142 // MATH OPERATORS
143 
145 {
146  v_[0] += v[0]; v_[1] += v[1]; v_[2] += v[2];
147  return *this;
148 }
149 
151 {
152  v_[0] -= v[0]; v_[1] -= v[1]; v_[2] -= v[2];
153  return *this;
154 }
155 
157 {
158  v_[0] *= c; v_[1] *= c; v_[2] *= c;
159  return *this;
160 }
161 
163 {
164  assert(!gmIsZero(c));
165  v_[0] /= c; v_[1] /= c; v_[2] /= c;
166  return *this;
167 }
168 
170 {
171  return gmVector3(v_[0] + v[0], v_[1] + v[1], v_[2] + v[2]);
172 }
173 
175 {
176  return gmVector3(v_[0] - v[0], v_[1] - v[1], v_[2] - v[2]);
177 }
178 
180 {
181  return gmVector3(-v_[0], -v_[1], -v_[2]);
182 }
183 
184 inline gmVector3 gmVector3::operator *(double c) const
185 {
186  return gmVector3(v_[0] * c, v_[1] * c, v_[2] * c);
187 }
188 
189 inline gmVector3 gmVector3::operator /(double c) const
190 {
191  assert(!gmIsZero(c));
192  return gmVector3(v_[0] / c, v_[1] / c, v_[2] / c);
193 }
194 
195 inline gmVector3 operator *(double c, const gmVector3& v)
196 {
197  return gmVector3(c * v[0], c * v[1], c * v[2]);
198 }
199 
200 inline bool gmVector3::operator ==(const gmVector3& v) const
201 {
202  return
203  (gmFuzEQ(v_[0], v[0]) && gmFuzEQ(v_[1], v[1]) && gmFuzEQ(v_[2], v[2]));
204 }
205 
206 inline bool gmVector3::operator !=(const gmVector3& v) const
207 {
208  return (!(*this == v));
209 }
210 
211 // OPERATIONS
212 
213 inline gmVector3& gmVector3::clamp(double lo, double hi)
214 {
215  gmClamp(v_[0], lo, hi); gmClamp(v_[1], lo, hi); gmClamp(v_[2], lo, hi);
216  return *this;
217 }
218 
219 inline double gmVector3::length() const
220 {
221  return sqrt(gmSqr(v_[0]) + gmSqr(v_[1]) + gmSqr(v_[2]));
222 }
223 
224 inline double gmVector3::lengthSquared() const
225 {
226  return gmSqr(v_[0]) + gmSqr(v_[1]) + gmSqr(v_[2]);
227 }
228 
230 {
231  double len = length();
232  //assert(!gmIsZero(len));
233  if (!gmIsZero(len)) *this /= len;
234  return *this;
235 }
236 
237 inline bool gmVector3::isZero()
238 {
239  return (gmIsZero(v_[0]) && gmIsZero(v_[1]) && gmIsZero(v_[2]));
240 }
241 
242 inline void gmVector3::copyTo(float f[3]) const
243 {
244  f[0] = v_[0]; f[1] = v_[1]; f[2] = v_[2];
245 }
246 
247 inline void gmVector3::copyTo(double f[3]) const
248 {
249  f[0] = v_[0]; f[1] = v_[1]; f[2] = v_[2];
250 }
251 
252 inline void gmVector3::float2double(const float *v)
253 {
254  v_[0] = (double) v[0];
255  v_[1] = (double) v[1];
256  v_[2] = (double) v[2];
257 }
258 
259 inline void gmVector3::double2float(const double *v)
260 {
261 // fit it to gl_lib!!!
262 //
263 // X(dest) = (float) X(v);
264 // Y(dest) = (float) Y(v);
265 // Z(dest) = (float) Z(v);
266 //
267 // return dest;
268 }
269 
270 inline gmVector3 cross(const gmVector3& v1, const gmVector3& v2)
271 {
272  return gmVector3(v1[1] * v2[2] - v1[2] * v2[1],
273  v1[2] * v2[0] - v1[0] * v2[2],
274  v1[0] * v2[1] - v1[1] * v2[0]);
275 }
276 
277 inline double distance(const gmVector3& v1, const gmVector3& v2)
278 {
279  return
280  sqrt(gmSqr(v1[0] - v2[0]) + gmSqr(v1[1] - v2[1]) + gmSqr(v1[2] - v2[2]));
281 }
282 
283 inline double distanceSquared(const gmVector3& v1, const gmVector3& v2)
284 {
285  return gmSqr(v1[0] - v2[0]) + gmSqr(v1[1] - v2[1]) + gmSqr(v1[2] - v2[2]);
286 }
287 
288 inline double dot(const gmVector3& v1, const gmVector3& v2)
289 {
290  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
291 }
292 
293 inline gmVector3 lerp(double f, const gmVector3& v1, const gmVector3& v2)
294 {
295  return v1 + ((v2 - v1) * f);
296 }
297 
298 // intersection of line given with point "p" and vector "v" and plane given
299 // with point "plane_p" and normal "plane_norm". This function returns "k" so,
300 // that INTERSECTION = p + k * v
301 inline double plane_intersect(const gmVector3& p, const gmVector3& v,
302  const gmVector3& plane_p, const gmVector3& plane_norm)
303 {
304  double d;
305 
306  d = dot(plane_norm, v);
307 
308  if (d == 0) // "plane_norm" and "v" are mutually parallel
309  return gmGOOGOL;
310 
311  gmVector3 tmp(plane_p);
312  tmp -= p;
313 
314  return dot(plane_norm, tmp) / d;
315 }
316 
317 inline double line_distance(const gmVector3& p1, const gmVector3& v1,
318  const gmVector3& p2, const gmVector3& v2)
319 {
320  gmVector3 norm = cross(v1, v2);
321 
322  return plane_intersect(p1, norm, p2, norm);
323 }
324 
325 // this function return "K" so that INTERSECTION = p + K * plane_norm =>
326 // we get an intersection "I" on the plane and from the vector | IK | we will
327 // determine distance of the point "p" to a plane.
328 inline double plane_distance(const gmVector3& p, const gmVector3& plane_p,
329  const gmVector3& plane_norm)
330 {
331  return plane_intersect(p, plane_norm, plane_p, plane_norm);
332 }
333 
334 // OUTPUT
335 
336 inline ostream & operator << ( ostream& os, const gmVector3& v)
337 {
338  os << "< " << v[0] << " " << v[1] << " " << v[2] << " >";
339  return os;
340 }
341 
342 #endif
343 
344 
345