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
moMathVector.cpp
Ir a la documentación de este archivo.
1 /*******************************************************************************
2 
3  moMathVector.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 "moMathVector.h"
39 
40 #include "moArray.h"
41 moDefineDynamicArray(moVector2iArray)
42 moDefineDynamicArray(moVector2fArray)
43 moDefineDynamicArray(moVector2fpArray)
44 moDefineDynamicArray(moVector2dArray)
45 
46 // moVector2 class ------------------------------------------------------------
47 /*
48 template <class Real>
49 moVector2<Real>::moVector2 ()
50 {
51  // uninitialized for performance in array construction
52 }
53 
54 
55 template <class Real>
56 moVector2<Real>::moVector2 (Real fX, Real fY)
57 {
58  m_afTuple[0] = fX;
59  m_afTuple[1] = fY;
60 }
61 
62 template <class Real>
63 moVector2<Real>::moVector2 (const Real* afTuple)
64 {
65  m_afTuple[0] = afTuple[0];
66  m_afTuple[1] = afTuple[1];
67 }
68 
69 template <class Real>
70 moVector2<Real>::moVector2 (const moVector2& rkV) : moAbstract(rkV)
71 {
72  m_afTuple[0] = rkV.m_afTuple[0];
73  m_afTuple[1] = rkV.m_afTuple[1];
74 }
75 
76 template <class Real>
77 int moVector2<Real>::CompareArrays (const moVector2& rkV) const
78 {
79  return memcmp(m_afTuple,rkV.m_afTuple,2*sizeof(Real));
80 }
81 
82 template <class Real>
83 bool moVector2<Real>::operator== (const moVector2& rkV) const
84 {
85  return CompareArrays(rkV) == 0;
86 }
87 
88 template <class Real>
89 bool moVector2<Real>::operator!= (const moVector2& rkV) const
90 {
91  return CompareArrays(rkV) != 0;
92 }
93 
94 template <class Real>
95 bool moVector2<Real>::operator< (const moVector2& rkV) const
96 {
97  return CompareArrays(rkV) < 0;
98 }
99 
100 template <class Real>
101 bool moVector2<Real>::operator<= (const moVector2& rkV) const
102 {
103  return CompareArrays(rkV) <= 0;
104 }
105 
106 template <class Real>
107 bool moVector2<Real>::operator> (const moVector2& rkV) const
108 {
109  return CompareArrays(rkV) > 0;
110 }
111 
112 template <class Real>
113 bool moVector2<Real>::operator>= (const moVector2& rkV) const
114 {
115  return CompareArrays(rkV) >= 0;
116 }
117 
118 template <class Real>
119 moVector2<Real> moVector2<Real>::operator+ (const moVector2& rkV) const
120 {
121  moVector2<Real> ret(m_afTuple[0]+rkV.m_afTuple[0], m_afTuple[1]+rkV.m_afTuple[1]);
122  return ret;
123 }
124 
125 template <class Real>
126 moVector2<Real> moVector2<Real>::operator- (const moVector2& rkV) const
127 {
128  moVector2<Real> ret(m_afTuple[0]-rkV.m_afTuple[0], m_afTuple[1]-rkV.m_afTuple[1]);
129  return ret;
130 }
131 */
132 /*
133 template <class Real>
134 moVector2<Real> moVector2<Real>::operator* (Real fScalar) const
135 {
136  moVector2<Real> ret(fScalar*m_afTuple[0], fScalar*m_afTuple[1]);
137  return ret;
138 }
139 
140 template <class Real>
141 moVector2<Real> moVector2<Real>::operator/ (Real fScalar) const
142 {
143  moVector2 kQuot;
144 
145  if (fScalar != (Real)0.0)
146  {
147  Real fInvScalar = ((Real)1.0)/fScalar;
148  kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
149  kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
150  }
151  else
152  {
153  kQuot.m_afTuple[0] = moMath<Real>::MAX_REAL;
154  kQuot.m_afTuple[1] = moMath<Real>::MAX_REAL;
155  }
156 
157  return kQuot;
158 }
159 
160 template <class Real>
161 moVector2<Real> moVector2<Real>::operator- () const
162 {
163  moVector2<Real> ret(-m_afTuple[0], -m_afTuple[1]);
164  return ret;
165 }
166 
167 template <class Real>
168 moVector2<Real>& moVector2<Real>::operator/= (Real fScalar)
169 {
170  if (fScalar != (Real)0.0)
171  {
172  Real fInvScalar = ((Real)1.0)/fScalar;
173  m_afTuple[0] *= fInvScalar;
174  m_afTuple[1] *= fInvScalar;
175  }
176  else
177  {
178  m_afTuple[0] = moMath<Real>::MAX_REAL;
179  m_afTuple[1] = moMath<Real>::MAX_REAL;
180  }
181 
182  return *this;
183 }
184 */
185 /*
186 // vector operations
187 template <class Real>
188 Real moVector2<Real>::Length () const
189 {
190  return moMath<Real>::Sqrt(m_afTuple[0]*m_afTuple[0] + m_afTuple[1]*m_afTuple[1]);
191 }
192 
193 template <class Real>
194 Real moVector2<Real>::SquaredLength () const
195 {
196  return m_afTuple[0]*m_afTuple[0] + m_afTuple[1]*m_afTuple[1];
197 }
198 
199 template <class Real>
200 Real moVector2<Real>::Dot (const moVector2& rkV) const
201 {
202  return m_afTuple[0]*rkV.m_afTuple[0] + m_afTuple[1]*rkV.m_afTuple[1];
203 }
204 */
205 /*
206 template <class Real>
207 Real moVector2<Real>::Normalize ()
208 {
209  Real fLength = Length();
210 
211  if (fLength > moMath<Real>::ZERO_TOLERANCE)
212  {
213  Real fInvLength = ((Real)1.0)/fLength;
214  m_afTuple[0] *= fInvLength;
215  m_afTuple[1] *= fInvLength;
216  }
217  else
218  {
219  fLength = (Real)0.0;
220  m_afTuple[0] = (Real)0.0;
221  m_afTuple[1] = (Real)0.0;
222  }
223 
224  return fLength;
225 }
226 
227  // returns (y,-x)
228 template <class Real>
229 moVector2<Real> moVector2<Real>::Perp () const
230 {
231  moVector2<Real> ret(m_afTuple[1],-m_afTuple[0]);
232  return ret;
233 }
234 
235 // returns (y,-x)/sqrt(x*x+y*y)
236 template <class Real>
237 moVector2<Real> moVector2<Real>::UnitPerp () const
238 {
239  moVector2 kPerp(m_afTuple[1],-m_afTuple[0]);
240  kPerp.Normalize();
241  return kPerp;
242 }
243 
244 // returns DotPerp((x,y),(V.x,V.y)) = x*V.y - y*V.x
245 template <class Real>
246 Real moVector2<Real>::DotPerp (const moVector2& rkV) const
247 {
248  return m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0];
249 }
250 
251 template <class Real>
252 void moVector2<Real>::GetBarycentrics (const moVector2& rkV0, const moVector2& rkV1,
253  const moVector2& rkV2, Real afBary[3]) const
254 {
255  // compute the vectors relative to V2 of the triangle
256  moVector2 akDiff[3] =
257  {
258  rkV0 - rkV2,
259  rkV1 - rkV2,
260  *this - rkV2
261  };
262 
263  // If the vertices have large magnitude, the linear system of equations
264  // for computing barycentric coordinates can be ill-conditioned. To avoid
265  // this, uniformly scale the triangle edges to be of order 1. The scaling
266  // of all differences does not change the barycentric coordinates.
267  Real fMax = (Real)0.0;
268  int i;
269  for (i = 0; i < 2; i++)
270  {
271  for (int j = 0; j < 2; j++)
272  {
273  Real fValue = moMath<Real>::FAbs(akDiff[i][j]);
274  if (fValue > fMax)
275  {
276  fMax = fValue;
277  }
278  }
279  }
280 
281  // scale down only large data
282  if (fMax > (Real)1.0)
283  {
284  Real fInvMax = ((Real)1.0)/fMax;
285  for (i = 0; i < 3; i++)
286  {
287  akDiff[i] *= fInvMax;
288  }
289  }
290 
291  Real fDet = akDiff[0].DotPerp(akDiff[1]);
292  if (moMath<Real>::FAbs(fDet) > moMath<Real>::ZERO_TOLERANCE)
293  {
294  Real fInvDet = ((Real)1.0)/fDet;
295  afBary[0] = akDiff[2].DotPerp(akDiff[1])*fInvDet;
296  afBary[1] = akDiff[0].DotPerp(akDiff[2])*fInvDet;
297  afBary[2] = (Real)1.0 - afBary[0] - afBary[1];
298  }
299  else
300  {
301  // The triangle is a sliver. Determine the longest edge and
302  // compute barycentric coordinates with respect to that edge.
303  moVector2 kE2 = rkV0 - rkV1;
304  Real fMaxSqrLength = kE2.SquaredLength();
305  int iMaxIndex = 2;
306  Real fSqrLength = akDiff[1].SquaredLength();
307  if (fSqrLength > fMaxSqrLength)
308  {
309  iMaxIndex = 1;
310  fMaxSqrLength = fSqrLength;
311  }
312  fSqrLength = akDiff[0].SquaredLength();
313  if (fSqrLength > fMaxSqrLength)
314  {
315  iMaxIndex = 0;
316  fMaxSqrLength = fSqrLength;
317  }
318 
319  if (fMaxSqrLength > moMath<Real>::ZERO_TOLERANCE)
320  {
321  Real fInvSqrLength = ((Real)1.0)/fMaxSqrLength;
322  if (iMaxIndex == 0)
323  {
324  // P-V2 = t(V0-V2)
325  afBary[0] = akDiff[2].Dot(akDiff[0])*fInvSqrLength;
326  afBary[1] = (Real)0.0;
327  afBary[2] = (Real)1.0 - afBary[0];
328  }
329  else if (iMaxIndex == 1)
330  {
331  // P-V2 = t(V1-V2)
332  afBary[0] = (Real)0.0;
333  afBary[1] = akDiff[2].Dot(akDiff[1])*fInvSqrLength;
334  afBary[2] = (Real)1.0 - afBary[1];
335  }
336  else
337  {
338  // P-V1 = t(V0-V1)
339  akDiff[2] = *this - rkV1;
340  afBary[0] = akDiff[2].Dot(kE2)*fInvSqrLength;
341  afBary[1] = (Real)1.0 - afBary[0];
342  afBary[2] = (Real)0.0;
343  }
344  }
345  else
346  {
347  // triangle is a nearly a point, just return equal weights
348  afBary[0] = ((Real)1.0)/(Real)3.0;
349  afBary[1] = afBary[0];
350  afBary[2] = afBary[0];
351  }
352  }
353 }
354 
355 template <class Real>
356 void moVector2<Real>::Orthonormalize (moVector2& rkU, moVector2& rkV)
357 {
358  // If the input vectors are v0 and v1, then the Gram-Schmidt
359  // orthonormalization produces vectors u0 and u1 as follows,
360  //
361  // u0 = v0/|v0|
362  // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
363  //
364  // where |A| indicates length of vector A and A*B indicates dot
365  // product of vectors A and B.
366 
367  // compute u0
368  rkU.Normalize();
369 
370  // compute u1
371  Real fDot0 = rkU.Dot(rkV);
372  rkV -= rkU*fDot0;
373  rkV.Normalize();
374 }
375 
376 template <class Real>
377 void moVector2<Real>::GenerateOrthonormalBasis (moVector2& rkU, moVector2& rkV)
378 {
379  rkV.Normalize();
380  rkU = rkV.Perp();
381 }
382 
383 template <class Real>
384 void moVector2<Real>::ComputeExtremes (int iVQuantity, const moVector2* akPoint,
385  moVector2& rkMin, moVector2& rkMax)
386 {
387  if (!(iVQuantity > 0 && akPoint)) return;
388 
389  rkMin = akPoint[0];
390  rkMax = rkMin;
391  for (int i = 1; i < iVQuantity; i++)
392  {
393  const moVector2<Real>& rkPoint = akPoint[i];
394  for (int j = 0; j < 2; j++)
395  {
396  if (rkPoint[j] < rkMin[j])
397  {
398  rkMin[j] = rkPoint[j];
399  }
400  else if (rkPoint[j] > rkMax[j])
401  {
402  rkMax[j] = rkPoint[j];
403  }
404  }
405  }
406 }
407 
408 // Cosine between 'this' vector and rkV.
409 template <class Real>
410 Real moVector2<Real>::Cosine (const moVector2<Real>& rkV)
411 {
412  Real l = Length();
413  Real lv = rkV.Length();
414  if ((0 < l) && (0 < lv)) return Dot(rkV) / (l * lv);
415  else return 0;
416 }
417 // Angle between 'this' vector and rkV.
418 template <class Real>
419 Real moVector2<Real>::Angle (const moVector2<Real>& rkV) {
420  return moMath<Real>::ACos(Cosine(rkV));
421 }
422 */
423 template<> const moVector2<MOlong> moVector2<MOlong>::ZERO(0,0);
424 template<> const moVector2<MOlong> moVector2<MOlong>::UNIT_X(1,0);
425 template<> const moVector2<MOlong> moVector2<MOlong>::UNIT_Y(0,1);
426 template<> const moVector2<MOlong> moVector2<MOlong>::ONE(1,1);
427 
428 template<> const moVector2<MOfloat> moVector2<MOfloat>::ZERO(0.0f,0.0f);
429 template<> const moVector2<MOfloat> moVector2<MOfloat>::UNIT_X(1.0f,0.0f);
430 template<> const moVector2<MOfloat> moVector2<MOfloat>::UNIT_Y(0.0f,1.0f);
431 template<> const moVector2<MOfloat> moVector2<MOfloat>::ONE(1.0f,1.0f);
432 
433 template<> const moVector2<MOdouble> moVector2<MOdouble>::ZERO(0.0,0.0);
434 template<> const moVector2<MOdouble> moVector2<MOdouble>::UNIT_X(1.0,0.0);
435 template<> const moVector2<MOdouble> moVector2<MOdouble>::UNIT_Y(0.0,1.0);
436 template<> const moVector2<MOdouble> moVector2<MOdouble>::ONE(1.0,1.0);
437 
438 
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