libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moMathVector3.h
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moMathVector.h
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright(C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28  Andrés Colubri
29 
30  Portions taken from
31  Wild Magic Source Code
32  David Eberly
33  http://www.geometrictools.com
34  Copyright (c) 1998-2007
35 
36 *******************************************************************************/
37 
38 #include "moMath.h"
39 
40 #ifndef __MO_MATH_VECTOR3_H__
41 #define __MO_MATH_VECTOR3_H__
42 
43 // moVector3 class ------------------------------------------------------------
44 
45 template <class Real>
47 {
48 public:
49  // construction
50  moVector3 () {} // uninitialized
51  moVector3 (Real fX, Real fY, Real fZ) {
52  m_afTuple[0] = fX;
53  m_afTuple[1] = fY;
54  m_afTuple[2] = fZ;
55  }
56  moVector3 (const Real* afTuple) {
57  m_afTuple[0] = afTuple[0];
58  m_afTuple[1] = afTuple[1];
59  m_afTuple[2] = afTuple[2];
60  }
61  moVector3 (const moVector3& rkV) : moAbstract(rkV) {
62  m_afTuple[0] = rkV.m_afTuple[0];
63  m_afTuple[1] = rkV.m_afTuple[1];
64  m_afTuple[2] = rkV.m_afTuple[2];
65  }
66 
67  // coordinate access
68  inline operator const Real* () const { return m_afTuple; }
69  inline operator Real* () { return m_afTuple; }
70 
71  inline Real operator[] (int i) const { return m_afTuple[i]; }
72  inline Real& operator[] (int i) { return m_afTuple[i]; }
73  inline Real X () const { return m_afTuple[0]; }
74  inline Real& X () { return m_afTuple[0]; }
75  inline Real Y () const { return m_afTuple[1]; }
76  inline Real& Y () { return m_afTuple[1]; }
77  inline Real Z () const { return m_afTuple[2]; }
78  inline Real& Z () { return m_afTuple[2]; }
79 
80  // assignment
81  inline moVector3& operator= (const moVector3& rkV)
82  {
83  m_afTuple[0] = rkV.m_afTuple[0];
84  m_afTuple[1] = rkV.m_afTuple[1];
85  m_afTuple[2] = rkV.m_afTuple[2];
86  return *this;
87  }
88 
89  // comparison
90  bool operator== (const moVector3& rkV) const { return CompareArrays(rkV) == 0; }
91  bool operator!= (const moVector3& rkV) const { return CompareArrays(rkV) != 0; }
92  bool operator< (const moVector3& rkV) const { return CompareArrays(rkV) < 0; }
93  bool operator<= (const moVector3& rkV) const { return CompareArrays(rkV) <= 0; }
94  bool operator> (const moVector3& rkV) const { return CompareArrays(rkV) > 0; }
95  bool operator>= (const moVector3& rkV) const { return CompareArrays(rkV) >= 0; }
96 
97  // arithmetic operations
98 
99  moVector3 operator+ (const moVector3& rkV) const {
100  moVector3<Real> ret(m_afTuple[0]+rkV.m_afTuple[0], m_afTuple[1]+rkV.m_afTuple[1], m_afTuple[2]+rkV.m_afTuple[2]);
101  return ret;
102  }
103  moVector3 operator- (const moVector3& rkV) const {
104  return moVector3<Real>(m_afTuple[0]-rkV.m_afTuple[0],m_afTuple[1]-rkV.m_afTuple[1],m_afTuple[2]-rkV.m_afTuple[2]);
105  }
106  moVector3 operator* (Real fScalar) const {
107  return moVector3<Real>(
108  fScalar*m_afTuple[0],
109  fScalar*m_afTuple[1],
110  fScalar*m_afTuple[2]);
111  }
112  moVector3 operator/ (Real fScalar) const {
113  moVector3<Real> kQuot;
114 
115  if (fScalar != (Real)0.0)
116  {
117  Real fInvScalar = ((Real)1.0)/fScalar;
118  kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
119  kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
120  kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
121  }
122  else
123  {
124  kQuot.m_afTuple[0] = moMath<Real>::MAX_REAL;
125  kQuot.m_afTuple[1] = moMath<Real>::MAX_REAL;
126  kQuot.m_afTuple[2] = moMath<Real>::MAX_REAL;
127  }
128 
129  return kQuot;
130  }
131 
133  return moVector3<Real>(-m_afTuple[0], -m_afTuple[1], -m_afTuple[2]);
134  }
135 
136  // arithmetic updates
137 
139  {
140  m_afTuple[0] += rkV.m_afTuple[0];
141  m_afTuple[1] += rkV.m_afTuple[1];
142  m_afTuple[2] += rkV.m_afTuple[2];
143  return *this;
144  }
145 
147  {
148  m_afTuple[0] -= rkV.m_afTuple[0];
149  m_afTuple[1] -= rkV.m_afTuple[1];
150  m_afTuple[2] -= rkV.m_afTuple[2];
151  return *this;
152  }
153 
154  moVector3<Real>& operator*= (const Real fScalar)
155  {
156  m_afTuple[0] *= fScalar;
157  m_afTuple[1] *= fScalar;
158  m_afTuple[2] *= fScalar;
159  return *this;
160  }
161 
162  moVector3<Real>& operator/= (const Real fScalar)
163  {
164  if (fScalar != (Real)0.0)
165  {
166  Real fInvScalar = ((Real)1.0)/fScalar;
167  m_afTuple[0] *= fInvScalar;
168  m_afTuple[1] *= fInvScalar;
169  m_afTuple[2] *= fInvScalar;
170  }
171  else
172  {
173  m_afTuple[0] = moMath<Real>::MAX_REAL;
174  m_afTuple[1] = moMath<Real>::MAX_REAL;
175  m_afTuple[2] = moMath<Real>::MAX_REAL;
176  }
177 
178  return *this;
179  }
180 
181 
182  // vector operations
183  Real Length () const {
184  return moMath<Real>::Sqrt(
185  m_afTuple[0]*m_afTuple[0] +
186  m_afTuple[1]*m_afTuple[1] +
187  m_afTuple[2]*m_afTuple[2]);
188  }
189 
190  Real SquaredLength () const
191  {
192  return
193  m_afTuple[0]*m_afTuple[0] +
194  m_afTuple[1]*m_afTuple[1] +
195  m_afTuple[2]*m_afTuple[2];
196  }
197 
198  Real Dot (const moVector3& rkV) const
199  {
200  return
201  m_afTuple[0]*rkV.m_afTuple[0] +
202  m_afTuple[1]*rkV.m_afTuple[1] +
203  m_afTuple[2]*rkV.m_afTuple[2];
204  }
205  Real Normalize () {
206  Real fLength = Length();
207 
208  if (fLength > moMath<Real>::ZERO_TOLERANCE)
209  {
210  Real fInvLength = ((Real)1.0)/fLength;
211  m_afTuple[0] *= fInvLength;
212  m_afTuple[1] *= fInvLength;
213  m_afTuple[2] *= fInvLength;
214  }
215  else
216  {
217  fLength = (Real)0.0;
218  m_afTuple[0] = (Real)0.0;
219  m_afTuple[1] = (Real)0.0;
220  m_afTuple[2] = (Real)0.0;
221  }
222 
223  return fLength;
224  }
225 
226  // The cross products are computed using the right-handed rule. Be aware
227  // that some graphics APIs use a left-handed rule. If you have to compute
228  // a cross product with these functions and send the result to the API
229  // that expects left-handed, you will need to change sign on the vector
230  // (replace each component value c by -c).
231  moVector3 Cross (const moVector3& rkV) const {
232  moVector3<Real> kCross(
233  m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
234  m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
235  m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
236  return kCross;
237  }
238  moVector3 UnitCross (const moVector3& rkV) const {
239  moVector3<Real> kCross(
240  m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
241  m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
242  m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
243  kCross.Normalize();
244  return kCross;
245  }
246 
247 
248  // Compute the barycentric coordinates of the point with respect to the
249  // tetrahedron <V0,V1,V2,V3>, P = b0*V0 + b1*V1 + b2*V2 + b3*V3, where
250  // b0 + b1 + b2 + b3 = 1.
251  void GetBarycentrics (const moVector3<Real>& rkV0,
252  const moVector3<Real>& rkV1, const moVector3<Real>& rkV2,
253  const moVector3<Real>& rkV3, Real afBary[4]) const
254  {
255  // compute the vectors relative to V3 of the tetrahedron
256  moVector3<Real> akDiff[4] =
257  {
258  rkV0 - rkV3,
259  rkV1 - rkV3,
260  rkV2 - rkV3,
261  *this - rkV3
262  };
263 
264  // If the vertices have large magnitude, the linear system of
265  // equations for computing barycentric coordinates can be
266  // ill-conditioned. To avoid this, uniformly scale the tetrahedron
267  // edges to be of order 1. The scaling of all differences does not
268  // change the barycentric coordinates.
269  Real fMax = (Real)0.0;
270  int i;
271  for (i = 0; i < 3; i++)
272  {
273  for (int j = 0; j < 3; j++)
274  {
275  Real fValue = moMath<Real>::FAbs(akDiff[i][j]);
276  if (fValue > fMax)
277  {
278  fMax = fValue;
279  }
280  }
281  }
282 
283  // scale down only large data
284  if (fMax > (Real)1.0)
285  {
286  Real fInvMax = ((Real)1.0)/fMax;
287  for (i = 0; i < 4; i++)
288  {
289  akDiff[i] *= fInvMax;
290  }
291  }
292 
293  Real fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
294  moVector3<Real> kE1cE2 = akDiff[1].Cross(akDiff[2]);
295  moVector3<Real> kE2cE0 = akDiff[2].Cross(akDiff[0]);
296  moVector3<Real> kE0cE1 = akDiff[0].Cross(akDiff[1]);
298  {
299  Real fInvDet = ((Real)1.0)/fDet;
300  afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
301  afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
302  afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
303  afBary[3] = (Real)1.0 - afBary[0] - afBary[1] - afBary[2];
304  }
305  else
306  {
307  // The tetrahedron is potentially flat. Determine the face of
308  // maximum area and compute barycentric coordinates with respect
309  // to that face.
310  moVector3<Real> kE02 = rkV0 - rkV2;
311  moVector3<Real> kE12 = rkV1 - rkV2;
312  moVector3<Real> kE02cE12 = kE02.Cross(kE12);
313  Real fMaxSqrArea = kE02cE12.SquaredLength();
314  int iMaxIndex = 3;
315  Real fSqrArea = kE0cE1.SquaredLength();
316  if (fSqrArea > fMaxSqrArea)
317  {
318  iMaxIndex = 0;
319  fMaxSqrArea = fSqrArea;
320  }
321  fSqrArea = kE1cE2.SquaredLength();
322  if (fSqrArea > fMaxSqrArea)
323  {
324  iMaxIndex = 1;
325  fMaxSqrArea = fSqrArea;
326  }
327  fSqrArea = kE2cE0.SquaredLength();
328  if (fSqrArea > fMaxSqrArea)
329  {
330  iMaxIndex = 2;
331  fMaxSqrArea = fSqrArea;
332  }
333 
334  if (fMaxSqrArea > moMath<Real>::ZERO_TOLERANCE)
335  {
336  Real fInvSqrArea = ((Real)1.0)/fMaxSqrArea;
337  moVector3<Real> kTmp;
338  if (iMaxIndex == 0)
339  {
340  kTmp = akDiff[3].Cross(akDiff[1]);
341  afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
342  kTmp = akDiff[0].Cross(akDiff[3]);
343  afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
344  afBary[2] = (Real)0.0;
345  afBary[3] = (Real)1.0 - afBary[0] - afBary[1];
346  }
347  else if (iMaxIndex == 1)
348  {
349  afBary[0] = (Real)0.0;
350  kTmp = akDiff[3].Cross(akDiff[2]);
351  afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
352  kTmp = akDiff[1].Cross(akDiff[3]);
353  afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
354  afBary[3] = (Real)1.0 - afBary[1] - afBary[2];
355  }
356  else if (iMaxIndex == 2)
357  {
358  kTmp = akDiff[2].Cross(akDiff[3]);
359  afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
360  afBary[1] = (Real)0.0;
361  kTmp = akDiff[3].Cross(akDiff[0]);
362  afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
363  afBary[3] = (Real)1.0 - afBary[0] - afBary[2];
364  }
365  else
366  {
367  akDiff[3] = *this - rkV2;
368  kTmp = akDiff[3].Cross(kE12);
369  afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
370  kTmp = kE02.Cross(akDiff[3]);
371  afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
372  afBary[2] = (Real)1.0 - afBary[0] - afBary[1];
373  afBary[3] = (Real)0.0;
374  }
375  }
376  else
377  {
378  // The tetrahedron is potentially a sliver. Determine the edge of
379  // maximum length and compute barycentric coordinates with respect
380  // to that edge.
381  Real fMaxSqrLength = akDiff[0].SquaredLength();
382  iMaxIndex = 0; // <V0,V3>
383  Real fSqrLength = akDiff[1].SquaredLength();
384  if (fSqrLength > fMaxSqrLength)
385  {
386  iMaxIndex = 1; // <V1,V3>
387  fMaxSqrLength = fSqrLength;
388  }
389  fSqrLength = akDiff[2].SquaredLength();
390  if (fSqrLength > fMaxSqrLength)
391  {
392  iMaxIndex = 2; // <V2,V3>
393  fMaxSqrLength = fSqrLength;
394  }
395  fSqrLength = kE02.SquaredLength();
396  if (fSqrLength > fMaxSqrLength)
397  {
398  iMaxIndex = 3; // <V0,V2>
399  fMaxSqrLength = fSqrLength;
400  }
401  fSqrLength = kE12.SquaredLength();
402  if (fSqrLength > fMaxSqrLength)
403  {
404  iMaxIndex = 4; // <V1,V2>
405  fMaxSqrLength = fSqrLength;
406  }
407  moVector3<Real> kE01 = rkV0 - rkV1;
408  fSqrLength = kE01.SquaredLength();
409  if (fSqrLength > fMaxSqrLength)
410  {
411  iMaxIndex = 5; // <V0,V1>
412  fMaxSqrLength = fSqrLength;
413  }
414 
415  if (fMaxSqrLength > moMath<Real>::ZERO_TOLERANCE)
416  {
417  Real fInvSqrLength = ((Real)1.0)/fMaxSqrLength;
418  if (iMaxIndex == 0)
419  {
420  // P-V3 = t*(V0-V3)
421  afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
422  afBary[1] = (Real)0.0;
423  afBary[2] = (Real)0.0;
424  afBary[3] = (Real)1.0 - afBary[0];
425  }
426  else if (iMaxIndex == 1)
427  {
428  // P-V3 = t*(V1-V3)
429  afBary[0] = (Real)0.0;
430  afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
431  afBary[2] = (Real)0.0;
432  afBary[3] = (Real)1.0 - afBary[1];
433  }
434  else if (iMaxIndex == 2)
435  {
436  // P-V3 = t*(V2-V3)
437  afBary[0] = (Real)0.0;
438  afBary[1] = (Real)0.0;
439  afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
440  afBary[3] = (Real)1.0 - afBary[2];
441  }
442  else if (iMaxIndex == 3)
443  {
444  // P-V2 = t*(V0-V2)
445  akDiff[3] = *this - rkV2;
446  afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
447  afBary[1] = (Real)0.0;
448  afBary[2] = (Real)1.0 - afBary[0];
449  afBary[3] = (Real)0.0;
450  }
451  else if (iMaxIndex == 4)
452  {
453  // P-V2 = t*(V1-V2)
454  akDiff[3] = *this - rkV2;
455  afBary[0] = (Real)0.0;
456  afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
457  afBary[2] = (Real)1.0 - afBary[1];
458  afBary[3] = (Real)0.0;
459  }
460  else
461  {
462  // P-V1 = t*(V0-V1)
463  akDiff[3] = *this - rkV1;
464  afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
465  afBary[1] = (Real)1.0 - afBary[0];
466  afBary[2] = (Real)0.0;
467  afBary[3] = (Real)0.0;
468  }
469  }
470  else
471  {
472  // tetrahedron is a nearly a point, just return equal weights
473  afBary[0] = (Real)0.25;
474  afBary[1] = afBary[0];
475  afBary[2] = afBary[0];
476  afBary[3] = afBary[0];
477  }
478  }
479  }
480  }
481 
482  // Gram-Schmidt orthonormalization. Take linearly independent vectors
483  // U, V, and W and compute an orthonormal set (unit length, mutually
484  // perpendicular).
485  static void Orthonormalize (moVector3& rkU, moVector3& rkV, moVector3& rkW)
486  {
487  // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
488  // orthonormalization produces vectors u0, u1, and u2 as follows,
489  //
490  // u0 = v0/|v0|
491  // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
492  // u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
493  //
494  // where |A| indicates length of vector A and A*B indicates dot
495  // product of vectors A and B.
496 
497  // compute u0
498  rkU.Normalize();
499 
500  // compute u1
501  Real fDot0 = rkU.Dot(rkV);
502  rkV -= fDot0*rkU;
503  rkV.Normalize();
504 
505  // compute u2
506  Real fDot1 = rkV.Dot(rkW);
507  fDot0 = rkU.Dot(rkW);
508  rkW -= fDot0*rkU + fDot1*rkV;
509  rkW.Normalize();
510  }
511 
512 
513  static void Orthonormalize (moVector3* akV)
514  {
515  Orthonormalize(akV[0],akV[1],akV[2]);
516  }
517 
518  // Input W must be a nonzero vector. The output is an orthonormal basis
519  // {U,V,W}. The input W is normalized by this function. If you know
520  // W is already unit length, use GenerateComplementBasis to compute U
521  // and V.
523  moVector3& rkW)
524  {
525  rkW.Normalize();
526  GenerateComplementBasis(rkU,rkV,rkW);
527  }
528 
529  // Input W must be a unit-length vector. The output vectors {U,V} are
530  // unit length and mutually perpendicular, and {U,V,W} is an orthonormal
531  // basis.
532  static void GenerateComplementBasis (moVector3& rkU, moVector3& rkV,
533  const moVector3& rkW)
534  {
535  Real fInvLength;
536 
537  if (moMath<Real>::FAbs(rkW.m_afTuple[0]) >=
538  moMath<Real>::FAbs(rkW.m_afTuple[1]) )
539  {
540  // W.x or W.z is the largest magnitude component, swap them
541  fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] +
542  rkW.m_afTuple[2]*rkW.m_afTuple[2]);
543  rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
544  rkU.m_afTuple[1] = (Real)0.0;
545  rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
546  rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2];
547  rkV.m_afTuple[1] = rkW.m_afTuple[2]*rkU.m_afTuple[0] -
548  rkW.m_afTuple[0]*rkU.m_afTuple[2];
549  rkV.m_afTuple[2] = -rkW.m_afTuple[1]*rkU.m_afTuple[0];
550  }
551  else
552  {
553  // W.y or W.z is the largest magnitude component, swap them
554  fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] +
555  rkW.m_afTuple[2]*rkW.m_afTuple[2]);
556  rkU.m_afTuple[0] = (Real)0.0;
557  rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
558  rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
559  rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2] -
560  rkW.m_afTuple[2]*rkU.m_afTuple[1];
561  rkV.m_afTuple[1] = -rkW.m_afTuple[0]*rkU.m_afTuple[2];
562  rkV.m_afTuple[2] = rkW.m_afTuple[0]*rkU.m_afTuple[1];
563  }
564  }
565 
566 
567  // Compute the extreme values.
568  static void ComputeExtremes (int iVQuantity, const moVector3* akPoint,
569  moVector3& rkMin, moVector3& rkMax)
570  {
571  if (!(iVQuantity > 0 && akPoint)) return;
572 
573  rkMin = akPoint[0];
574  rkMax = rkMin;
575  for (int i = 1; i < iVQuantity; i++)
576  {
577  const moVector3<Real>& rkPoint = akPoint[i];
578  for (int j = 0; j < 3; j++)
579  {
580  if (rkPoint[j] < rkMin[j])
581  {
582  rkMin[j] = rkPoint[j];
583  }
584  else if (rkPoint[j] > rkMax[j])
585  {
586  rkMax[j] = rkPoint[j];
587  }
588  }
589  }
590  }
591 
592 
593  // Cosine between 'this' vector and rkV.
594  Real Cosine (const moVector3<Real>& rkV) {
595  Real l = Length();
596  Real lv = rkV.Length();
597  if ((0 < l) && (0 < lv)) return Dot(rkV) / (l * lv);
598  else return 0;
599  }
600  // Angle between 'this' vector and rkV.
601  Real Angle (const moVector3<Real>& rkV) {
602  return moMath<Real>::ACos(Cosine(rkV));
603  }
604 
605  // special vectors
606  static const moVector3 ZERO; // (0,0,0)
607  static const moVector3 UNIT_X; // (1,0,0)
608  static const moVector3 UNIT_Y; // (0,1,0)
609  static const moVector3 UNIT_Z; // (0,0,1)
610  static const moVector3 ONE; // (1,1,1)
611 
612 private:
613  // support for comparisons
614  int CompareArrays (const moVector3& rkV) const {return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(Real));}
615 
616  Real m_afTuple[3];
617 };
618 
619 
620 // arithmetic operations
621 template <class Real>
622 inline moVector3<Real> operator* (Real fScalar, const moVector3<Real>& rkV)
623 {
624  return moVector3<Real>(fScalar*rkV[0], fScalar*rkV[1], fScalar*rkV[2]);
625 }
626 
627 #ifndef MO_MACOSX
628 #ifndef MO_RASPBIAN
632 #endif
633 #endif
634 
635 typedef moVector3<MOlong> moVector3i;
636 typedef moVector3<MOfloat> moVector3f;
637 typedef moVector3<MOdouble> moVector3d;
641 
642 moDeclareExportedDynamicArray( moVector3i, moVector3iArray );
643 moDeclareExportedDynamicArray( moVector3f, moVector3fArray );
644 moDeclareExportedDynamicArray( moVector3d, moVector3dArray );
645 
646 #endif
647 
Real Length() const
moVector3i moVertex3i
Real & Z()
Definition: moMathVector3.h:78
moVector3< Real > operator*(Real fScalar, const moVector3< Real > &rkV)
bool operator<=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:960
Real SquaredLength() const
moMatrix3 operator-(const moMatrix3 &rkM) const
static Real ACos(Real fValue)
Definition: moMath.h:81
moMatrix3 operator/(Real fScalar) const
bool operator>(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:966
Real Z() const
Definition: moMathVector3.h:77
static void ComputeExtremes(int iVQuantity, const moVector3 *akPoint, moVector3 &rkMin, moVector3 &rkMax)
moVector3d moVertex3d
Clase base abstracta de donde deben derivar los objetos [virtual pura].
Definition: moAbstract.h:191
Real & X()
Definition: moMathVector3.h:74
Real X() const
Definition: moMathVector3.h:73
#define LIBMOLDEO_API
Definition: moTypes.h:180
static void Orthonormalize(moVector3 *akV)
static const moVector3 ONE
static const moVector3 UNIT_X
moVector3(const Real *afTuple)
Definition: moMathVector3.h:56
moMatrix3 & operator-=(const moMatrix3 &rkM)
static const moVector3 UNIT_Y
static Real InvSqrt(Real fValue)
Definition: moMath.h:210
bool operator==(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:942
static Real Sqrt(Real fValue)
Definition: moMath.h:279
bool operator<(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:954
Real & Y()
Definition: moMathVector3.h:76
static const moVector3 UNIT_Z
Real Dot(const moVector3 &rkV) const
Real Normalize()
void Orthonormalize()
moMatrix3 & operator/=(Real fScalar)
void GetBarycentrics(const moVector3< Real > &rkV0, const moVector3< Real > &rkV1, const moVector3< Real > &rkV2, const moVector3< Real > &rkV3, Real afBary[4]) const
moVector3< MOdouble > moVector3d
moVector3(const moVector3 &rkV)
Definition: moMathVector3.h:61
moVector3 Cross(const moVector3 &rkV) const
moVector3(Real fX, Real fY, Real fZ)
Definition: moMathVector3.h:51
Real Y() const
Definition: moMathVector3.h:75
bool operator!=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:948
static void GenerateComplementBasis(moVector3 &rkU, moVector3 &rkV, const moVector3 &rkW)
moMatrix3 & operator*=(Real fScalar)
bool operator>=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:972
Real Cosine(const moVector3< Real > &rkV)
moMatrix3 & operator=(const moMatrix3 &rkM)
moVector3< MOlong > moVector3i
moDeclareExportedDynamicArray(moVector3i, moVector3iArray)
Definition: moMath.h:64
moVector3< MOfloat > moVector3f
Real Angle(const moVector3< Real > &rkV)
static const moVector3 ZERO
moMatrix3 operator+(const moMatrix3 &rkM) const
static Real FAbs(Real fValue)
Definition: moMath.h:180
moMatrix3 & operator+=(const moMatrix3 &rkM)
static void GenerateOrthonormalBasis(moVector3 &rkU, moVector3 &rkV, moVector3 &rkW)
moVector3f moVertex3f
static void Orthonormalize(moVector3 &rkU, moVector3 &rkV, moVector3 &rkW)
const Real * operator[](int iRow) const
moVector3 UnitCross(const moVector3 &rkV) const