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