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.cpp
Ir a la documentación de este archivo.
1 /*******************************************************************************
2 
3  moMathVector3.cpp
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 "moMathVector3.h"
39 
40 #include "moArray.h"
41 moDefineDynamicArray(moVector3iArray)
42 moDefineDynamicArray(moVector3fArray)
43 moDefineDynamicArray(moVector3dArray)
44 
45 // moVector3 class ------------------------------------------------------------
46 /*
47 template <class Real>
48 moVector3<Real>::moVector3 ()
49 {
50  // uninitialized for performance in array construction
51 }
52 
53 template <class Real>
54 moVector3<Real>::moVector3 (Real fX, Real fY, Real fZ)
55 {
56  m_afTuple[0] = fX;
57  m_afTuple[1] = fY;
58  m_afTuple[2] = fZ;
59 }
60 
61 template <class Real>
62 moVector3<Real>::moVector3 (const Real* afTuple)
63 {
64  m_afTuple[0] = afTuple[0];
65  m_afTuple[1] = afTuple[1];
66  m_afTuple[2] = afTuple[2];
67 }
68 */
69 /*
70 template <class Real>
71 moVector3<Real>::moVector3 (const moVector3& rkV) : moAbstract(rkV)
72 {
73  m_afTuple[0] = rkV.m_afTuple[0];
74  m_afTuple[1] = rkV.m_afTuple[1];
75  m_afTuple[2] = rkV.m_afTuple[2];
76 }
77 
78 template <class Real>
79 int moVector3<Real>::CompareArrays (const moVector3& rkV) const
80 {
81  return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(Real));
82 }
83 
84 template <class Real>
85 bool moVector3<Real>::operator== (const moVector3& rkV) const
86 {
87  return CompareArrays(rkV) == 0;
88 }
89 
90 template <class Real>
91 bool moVector3<Real>::operator!= (const moVector3& rkV) const
92 {
93  return CompareArrays(rkV) != 0;
94 }
95 
96 template <class Real>
97 bool moVector3<Real>::operator< (const moVector3& rkV) const
98 {
99  return CompareArrays(rkV) < 0;
100 }
101 
102 template <class Real>
103 bool moVector3<Real>::operator<= (const moVector3& rkV) const
104 {
105  return CompareArrays(rkV) <= 0;
106 }
107 
108 template <class Real>
109 bool moVector3<Real>::operator> (const moVector3& rkV) const
110 {
111  return CompareArrays(rkV) > 0;
112 }
113 
114 template <class Real>
115 bool moVector3<Real>::operator>= (const moVector3& rkV) const
116 {
117  return CompareArrays(rkV) >= 0;
118 }
119 
120 template <class Real>
121 void moVector3<Real>::GetBarycentrics (const moVector3<Real>& rkV0,
122  const moVector3<Real>& rkV1, const moVector3<Real>& rkV2,
123  const moVector3<Real>& rkV3, Real afBary[4]) const
124 {
125  // compute the vectors relative to V3 of the tetrahedron
126  moVector3<Real> akDiff[4] =
127  {
128  rkV0 - rkV3,
129  rkV1 - rkV3,
130  rkV2 - rkV3,
131  *this - rkV3
132  };
133 
134  // If the vertices have large magnitude, the linear system of
135  // equations for computing barycentric coordinates can be
136  // ill-conditioned. To avoid this, uniformly scale the tetrahedron
137  // edges to be of order 1. The scaling of all differences does not
138  // change the barycentric coordinates.
139  Real fMax = (Real)0.0;
140  int i;
141  for (i = 0; i < 3; i++)
142  {
143  for (int j = 0; j < 3; j++)
144  {
145  Real fValue = moMath<Real>::FAbs(akDiff[i][j]);
146  if (fValue > fMax)
147  {
148  fMax = fValue;
149  }
150  }
151  }
152 
153  // scale down only large data
154  if (fMax > (Real)1.0)
155  {
156  Real fInvMax = ((Real)1.0)/fMax;
157  for (i = 0; i < 4; i++)
158  {
159  akDiff[i] *= fInvMax;
160  }
161  }
162 
163  Real fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
164  moVector3<Real> kE1cE2 = akDiff[1].Cross(akDiff[2]);
165  moVector3<Real> kE2cE0 = akDiff[2].Cross(akDiff[0]);
166  moVector3<Real> kE0cE1 = akDiff[0].Cross(akDiff[1]);
167  if (moMath<Real>::FAbs(fDet) > moMath<Real>::ZERO_TOLERANCE)
168  {
169  Real fInvDet = ((Real)1.0)/fDet;
170  afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
171  afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
172  afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
173  afBary[3] = (Real)1.0 - afBary[0] - afBary[1] - afBary[2];
174  }
175  else
176  {
177  // The tetrahedron is potentially flat. Determine the face of
178  // maximum area and compute barycentric coordinates with respect
179  // to that face.
180  moVector3<Real> kE02 = rkV0 - rkV2;
181  moVector3<Real> kE12 = rkV1 - rkV2;
182  moVector3<Real> kE02cE12 = kE02.Cross(kE12);
183  Real fMaxSqrArea = kE02cE12.SquaredLength();
184  int iMaxIndex = 3;
185  Real fSqrArea = kE0cE1.SquaredLength();
186  if (fSqrArea > fMaxSqrArea)
187  {
188  iMaxIndex = 0;
189  fMaxSqrArea = fSqrArea;
190  }
191  fSqrArea = kE1cE2.SquaredLength();
192  if (fSqrArea > fMaxSqrArea)
193  {
194  iMaxIndex = 1;
195  fMaxSqrArea = fSqrArea;
196  }
197  fSqrArea = kE2cE0.SquaredLength();
198  if (fSqrArea > fMaxSqrArea)
199  {
200  iMaxIndex = 2;
201  fMaxSqrArea = fSqrArea;
202  }
203 
204  if (fMaxSqrArea > moMath<Real>::ZERO_TOLERANCE)
205  {
206  Real fInvSqrArea = ((Real)1.0)/fMaxSqrArea;
207  moVector3<Real> kTmp;
208  if (iMaxIndex == 0)
209  {
210  kTmp = akDiff[3].Cross(akDiff[1]);
211  afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
212  kTmp = akDiff[0].Cross(akDiff[3]);
213  afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
214  afBary[2] = (Real)0.0;
215  afBary[3] = (Real)1.0 - afBary[0] - afBary[1];
216  }
217  else if (iMaxIndex == 1)
218  {
219  afBary[0] = (Real)0.0;
220  kTmp = akDiff[3].Cross(akDiff[2]);
221  afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
222  kTmp = akDiff[1].Cross(akDiff[3]);
223  afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
224  afBary[3] = (Real)1.0 - afBary[1] - afBary[2];
225  }
226  else if (iMaxIndex == 2)
227  {
228  kTmp = akDiff[2].Cross(akDiff[3]);
229  afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
230  afBary[1] = (Real)0.0;
231  kTmp = akDiff[3].Cross(akDiff[0]);
232  afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
233  afBary[3] = (Real)1.0 - afBary[0] - afBary[2];
234  }
235  else
236  {
237  akDiff[3] = *this - rkV2;
238  kTmp = akDiff[3].Cross(kE12);
239  afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
240  kTmp = kE02.Cross(akDiff[3]);
241  afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
242  afBary[2] = (Real)1.0 - afBary[0] - afBary[1];
243  afBary[3] = (Real)0.0;
244  }
245  }
246  else
247  {
248  // The tetrahedron is potentially a sliver. Determine the edge of
249  // maximum length and compute barycentric coordinates with respect
250  // to that edge.
251  Real fMaxSqrLength = akDiff[0].SquaredLength();
252  iMaxIndex = 0; // <V0,V3>
253  Real fSqrLength = akDiff[1].SquaredLength();
254  if (fSqrLength > fMaxSqrLength)
255  {
256  iMaxIndex = 1; // <V1,V3>
257  fMaxSqrLength = fSqrLength;
258  }
259  fSqrLength = akDiff[2].SquaredLength();
260  if (fSqrLength > fMaxSqrLength)
261  {
262  iMaxIndex = 2; // <V2,V3>
263  fMaxSqrLength = fSqrLength;
264  }
265  fSqrLength = kE02.SquaredLength();
266  if (fSqrLength > fMaxSqrLength)
267  {
268  iMaxIndex = 3; // <V0,V2>
269  fMaxSqrLength = fSqrLength;
270  }
271  fSqrLength = kE12.SquaredLength();
272  if (fSqrLength > fMaxSqrLength)
273  {
274  iMaxIndex = 4; // <V1,V2>
275  fMaxSqrLength = fSqrLength;
276  }
277  moVector3<Real> kE01 = rkV0 - rkV1;
278  fSqrLength = kE01.SquaredLength();
279  if (fSqrLength > fMaxSqrLength)
280  {
281  iMaxIndex = 5; // <V0,V1>
282  fMaxSqrLength = fSqrLength;
283  }
284 
285  if (fMaxSqrLength > moMath<Real>::ZERO_TOLERANCE)
286  {
287  Real fInvSqrLength = ((Real)1.0)/fMaxSqrLength;
288  if (iMaxIndex == 0)
289  {
290  // P-V3 = t*(V0-V3)
291  afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
292  afBary[1] = (Real)0.0;
293  afBary[2] = (Real)0.0;
294  afBary[3] = (Real)1.0 - afBary[0];
295  }
296  else if (iMaxIndex == 1)
297  {
298  // P-V3 = t*(V1-V3)
299  afBary[0] = (Real)0.0;
300  afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
301  afBary[2] = (Real)0.0;
302  afBary[3] = (Real)1.0 - afBary[1];
303  }
304  else if (iMaxIndex == 2)
305  {
306  // P-V3 = t*(V2-V3)
307  afBary[0] = (Real)0.0;
308  afBary[1] = (Real)0.0;
309  afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
310  afBary[3] = (Real)1.0 - afBary[2];
311  }
312  else if (iMaxIndex == 3)
313  {
314  // P-V2 = t*(V0-V2)
315  akDiff[3] = *this - rkV2;
316  afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
317  afBary[1] = (Real)0.0;
318  afBary[2] = (Real)1.0 - afBary[0];
319  afBary[3] = (Real)0.0;
320  }
321  else if (iMaxIndex == 4)
322  {
323  // P-V2 = t*(V1-V2)
324  akDiff[3] = *this - rkV2;
325  afBary[0] = (Real)0.0;
326  afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
327  afBary[2] = (Real)1.0 - afBary[1];
328  afBary[3] = (Real)0.0;
329  }
330  else
331  {
332  // P-V1 = t*(V0-V1)
333  akDiff[3] = *this - rkV1;
334  afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
335  afBary[1] = (Real)1.0 - afBary[0];
336  afBary[2] = (Real)0.0;
337  afBary[3] = (Real)0.0;
338  }
339  }
340  else
341  {
342  // tetrahedron is a nearly a point, just return equal weights
343  afBary[0] = (Real)0.25;
344  afBary[1] = afBary[0];
345  afBary[2] = afBary[0];
346  afBary[3] = afBary[0];
347  }
348  }
349  }
350 }
351 
352 template <class Real>
353 void moVector3<Real>::Orthonormalize (moVector3& rkU, moVector3& rkV, moVector3& rkW)
354 {
355  // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
356  // orthonormalization produces vectors u0, u1, and u2 as follows,
357  //
358  // u0 = v0/|v0|
359  // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
360  // u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
361  //
362  // where |A| indicates length of vector A and A*B indicates dot
363  // product of vectors A and B.
364 
365  // compute u0
366  rkU.Normalize();
367 
368  // compute u1
369  Real fDot0 = rkU.Dot(rkV);
370  rkV -= fDot0*rkU;
371  rkV.Normalize();
372 
373  // compute u2
374  Real fDot1 = rkV.Dot(rkW);
375  fDot0 = rkU.Dot(rkW);
376  rkW -= fDot0*rkU + fDot1*rkV;
377  rkW.Normalize();
378 }
379 
380 template <class Real>
381 void moVector3<Real>::Orthonormalize (moVector3* akV)
382 {
383  Orthonormalize(akV[0],akV[1],akV[2]);
384 }
385 
386 template <class Real>
387 void moVector3<Real>::GenerateOrthonormalBasis (moVector3& rkU, moVector3& rkV,
388  moVector3& rkW)
389 {
390  rkW.Normalize();
391  GenerateComplementBasis(rkU,rkV,rkW);
392 }
393 
394 template <class Real>
395 void moVector3<Real>::GenerateComplementBasis (moVector3& rkU, moVector3& rkV,
396  const moVector3& rkW)
397 {
398  Real fInvLength;
399 
400  if (moMath<Real>::FAbs(rkW.m_afTuple[0]) >=
401  moMath<Real>::FAbs(rkW.m_afTuple[1]) )
402  {
403  // W.x or W.z is the largest magnitude component, swap them
404  fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] +
405  rkW.m_afTuple[2]*rkW.m_afTuple[2]);
406  rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
407  rkU.m_afTuple[1] = (Real)0.0;
408  rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
409  rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2];
410  rkV.m_afTuple[1] = rkW.m_afTuple[2]*rkU.m_afTuple[0] -
411  rkW.m_afTuple[0]*rkU.m_afTuple[2];
412  rkV.m_afTuple[2] = -rkW.m_afTuple[1]*rkU.m_afTuple[0];
413  }
414  else
415  {
416  // W.y or W.z is the largest magnitude component, swap them
417  fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] +
418  rkW.m_afTuple[2]*rkW.m_afTuple[2]);
419  rkU.m_afTuple[0] = (Real)0.0;
420  rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
421  rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
422  rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2] -
423  rkW.m_afTuple[2]*rkU.m_afTuple[1];
424  rkV.m_afTuple[1] = -rkW.m_afTuple[0]*rkU.m_afTuple[2];
425  rkV.m_afTuple[2] = rkW.m_afTuple[0]*rkU.m_afTuple[1];
426  }
427 }
428 
429 template <class Real>
430 void moVector3<Real>::ComputeExtremes (int iVQuantity, const moVector3* akPoint,
431  moVector3& rkMin, moVector3& rkMax)
432 {
433  if (!(iVQuantity > 0 && akPoint)) return;
434 
435  rkMin = akPoint[0];
436  rkMax = rkMin;
437  for (int i = 1; i < iVQuantity; i++)
438  {
439  const moVector3<Real>& rkPoint = akPoint[i];
440  for (int j = 0; j < 3; j++)
441  {
442  if (rkPoint[j] < rkMin[j])
443  {
444  rkMin[j] = rkPoint[j];
445  }
446  else if (rkPoint[j] > rkMax[j])
447  {
448  rkMax[j] = rkPoint[j];
449  }
450  }
451  }
452 }
453 
454 
455 // arithmetic operations
456 template <class Real>
457 moVector3<Real> moVector3<Real>::operator+ (const moVector3& rkV) const
458 {
459  moVector3<Real> ret(m_afTuple[0]+rkV.m_afTuple[0], m_afTuple[1]+rkV.m_afTuple[1], m_afTuple[2]+rkV.m_afTuple[2]);
460  return ret;
461 }
462 
463 
464 template <class Real>
465 moVector3<Real> moVector3<Real>::operator- (const moVector3& rkV) const
466 {
467  return moVector3<Real>(m_afTuple[0]-rkV.m_afTuple[0],m_afTuple[1]-rkV.m_afTuple[1],m_afTuple[2]-rkV.m_afTuple[2]);
468 }
469 
470 
471 template <class Real>
472 moVector3<Real> moVector3<Real>::operator* (Real fScalar) const
473 {
474  return moVector3<Real>(
475  fScalar*m_afTuple[0],
476  fScalar*m_afTuple[1],
477  fScalar*m_afTuple[2]);
478 }
479 
480 
481 template <class Real>
482 moVector3<Real> moVector3<Real>::operator/ (Real fScalar) const
483 {
484  moVector3<Real> kQuot;
485 
486  if (fScalar != (Real)0.0)
487  {
488  Real fInvScalar = ((Real)1.0)/fScalar;
489  kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
490  kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
491  kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
492  }
493  else
494  {
495  kQuot.m_afTuple[0] = moMath<Real>::MAX_REAL;
496  kQuot.m_afTuple[1] = moMath<Real>::MAX_REAL;
497  kQuot.m_afTuple[2] = moMath<Real>::MAX_REAL;
498  }
499 
500  return kQuot;
501 }
502 template <class Real>
503 moVector3<Real> moVector3<Real>::operator- () const
504 {
505  return moVector3<Real>(-m_afTuple[0], -m_afTuple[1], -m_afTuple[2]);
506 }
507 
508 // arithmetic updates
509 template <class Real>
510 moVector3<Real>& moVector3<Real>::operator+= (const moVector3& rkV)
511 {
512  m_afTuple[0] += rkV.m_afTuple[0];
513  m_afTuple[1] += rkV.m_afTuple[1];
514  m_afTuple[2] += rkV.m_afTuple[2];
515  return *this;
516 }
517 template <class Real>
518 moVector3<Real>& moVector3<Real>::operator-= (const moVector3& rkV)
519 {
520  m_afTuple[0] -= rkV.m_afTuple[0];
521  m_afTuple[1] -= rkV.m_afTuple[1];
522  m_afTuple[2] -= rkV.m_afTuple[2];
523  return *this;
524 }
525 template <class Real>
526 moVector3<Real>& moVector3<Real>::operator*= (const Real fScalar)
527 {
528  m_afTuple[0] *= fScalar;
529  m_afTuple[1] *= fScalar;
530  m_afTuple[2] *= fScalar;
531  return *this;
532 }
533 template <class Real>
534 moVector3<Real>& moVector3<Real>::operator/= (const Real fScalar)
535 {
536  if (fScalar != (Real)0.0)
537  {
538  Real fInvScalar = ((Real)1.0)/fScalar;
539  m_afTuple[0] *= fInvScalar;
540  m_afTuple[1] *= fInvScalar;
541  m_afTuple[2] *= fInvScalar;
542  }
543  else
544  {
545  m_afTuple[0] = moMath<Real>::MAX_REAL;
546  m_afTuple[1] = moMath<Real>::MAX_REAL;
547  m_afTuple[2] = moMath<Real>::MAX_REAL;
548  }
549 
550  return *this;
551 }
552 */
553 /*
554 // vector operations
555 template <class Real>
556 Real moVector3<Real>::Length () const
557 {
558  return moMath<Real>::Sqrt(
559  m_afTuple[0]*m_afTuple[0] +
560  m_afTuple[1]*m_afTuple[1] +
561  m_afTuple[2]*m_afTuple[2]);
562 }
563 
564 
565 template <class Real>
566 Real moVector3<Real>::SquaredLength () const
567 {
568  return
569  m_afTuple[0]*m_afTuple[0] +
570  m_afTuple[1]*m_afTuple[1] +
571  m_afTuple[2]*m_afTuple[2];
572 }
573 template <class Real>
574 Real moVector3<Real>::Dot (const moVector3& rkV) const
575 {
576  return
577  m_afTuple[0]*rkV.m_afTuple[0] +
578  m_afTuple[1]*rkV.m_afTuple[1] +
579  m_afTuple[2]*rkV.m_afTuple[2];
580 }
581 
582 
583 template <class Real>
584 Real moVector3<Real>::Normalize ()
585 {
586  Real fLength = Length();
587 
588  if (fLength > moMath<Real>::ZERO_TOLERANCE)
589  {
590  Real fInvLength = ((Real)1.0)/fLength;
591  m_afTuple[0] *= fInvLength;
592  m_afTuple[1] *= fInvLength;
593  m_afTuple[2] *= fInvLength;
594  }
595  else
596  {
597  fLength = (Real)0.0;
598  m_afTuple[0] = (Real)0.0;
599  m_afTuple[1] = (Real)0.0;
600  m_afTuple[2] = (Real)0.0;
601  }
602 
603  return fLength;
604 }
605 
606 // The cross products are computed using the right-handed rule. Be aware
607 // that some graphics APIs use a left-handed rule. If you have to compute
608 // a cross product with these functions and send the result to the API
609 // that expects left-handed, you will need to change sign on the vector
610 // (replace each component value c by -c).
611 
612 template <class Real>
613 moVector3<Real> moVector3<Real>::Cross (const moVector3& rkV) const
614 {
615  moVector3<Real> kCross(
616  m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
617  m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
618  m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
619  return kCross;
620 }
621 
622 template <class Real>
623 moVector3<Real> moVector3<Real>::UnitCross (const moVector3& rkV) const
624 {
625  moVector3<Real> kCross(
626  m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
627  m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
628  m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
629  kCross.Normalize();
630  return kCross;
631 }
632 
633 
634 // Cosine between 'this' vector and rkV.
635 template <class Real>
636 Real moVector3<Real>::Cosine (const moVector3<Real>& rkV)
637 {
638  Real l = Length();
639  Real lv = rkV.Length();
640  if ((0 < l) && (0 < lv)) return Dot(rkV) / (l * lv);
641  else return 0;
642 }
643 // Angle between 'this' vector and rkV.
644 template <class Real>
645 Real moVector3<Real>::Angle (const moVector3<Real>& rkV) {
646  return moMath<Real>::ACos(Cosine(rkV));
647 }
648 */
649 template<> const moVector3<MOlong> moVector3<MOlong>::ZERO(0,0,0);
650 template<> const moVector3<MOlong> moVector3<MOlong>::UNIT_X(1,0,0);
651 template<> const moVector3<MOlong> moVector3<MOlong>::UNIT_Y(0,1,0);
652 template<> const moVector3<MOlong> moVector3<MOlong>::UNIT_Z(0,0,1);
653 template<> const moVector3<MOlong> moVector3<MOlong>::ONE(1,1,1);
654 
655 template<> const moVector3<MOfloat> moVector3<MOfloat>::ZERO(0.0f,0.0f,0.0f);
656 template<> const moVector3<MOfloat> moVector3<MOfloat>::UNIT_X(1.0f,0.0f,0.0f);
657 template<> const moVector3<MOfloat> moVector3<MOfloat>::UNIT_Y(0.0f,1.0f,0.0f);
658 template<> const moVector3<MOfloat> moVector3<MOfloat>::UNIT_Z(0.0f,0.0f,1.0f);
659 template<> const moVector3<MOfloat> moVector3<MOfloat>::ONE(1.0f,1.0f,1.0f);
660 
661 template<> const moVector3<MOdouble> moVector3<MOdouble>::ZERO(0.0,0.0,0.0);
662 template<> const moVector3<MOdouble> moVector3<MOdouble>::UNIT_X(1.0,0.0,0.0);
663 template<> const moVector3<MOdouble> moVector3<MOdouble>::UNIT_Y(0.0,1.0,0.0);
664 template<> const moVector3<MOdouble> moVector3<MOdouble>::UNIT_Z(0.0,0.0,1.0);
665 template<> const moVector3<MOdouble> moVector3<MOdouble>::ONE(1.0,1.0,1.0);
666 
667 
f
Definition: jquery.js:71
#define MOfloat
Definition: moTypes.h:403
#define MOlong
Definition: moTypes.h:391
#define moDefineDynamicArray(name)
Definition: moArray.cpp:222
#define MOdouble
Definition: moTypes.h:404
moPort const
Definition: all_14.js:19