libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo es el conjunto de objetos y funciones, que permiten ejecutar las operaciones básicas de la plataforma Moldeo, y que compone su núcleo.
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Amigas 'defines' Grupos Páginas
moMathVector3.h
Ir a la documentación de este archivo.
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)
moTypes MOint moText moParamIndex moParamReference int iRow int int i int i
Definition: all_f.js:18
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