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
moMathVector.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_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)
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