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.
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
moMathVector.cpp
Go to the documentation of this file.
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
moArray.h
moVector2
Definition:
moMathVector.h:46
MOfloat
#define MOfloat
Definition:
moTypes.h:403
MOlong
#define MOlong
Definition:
moTypes.h:391
moMathVector.h
moDefineDynamicArray
#define moDefineDynamicArray(name)
Definition:
moArray.cpp:222
MOdouble
#define MOdouble
Definition:
moTypes.h:404
libmoldeo
moMathVector.cpp
Generated on Wed May 17 2017 14:09:18 for libmoldeo (Moldeo 1.0 Core) by
1.8.8