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.
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
moVector2::ZERO
static const moVector2 ZERO
Definition:
moMathVector.h:391
moArray.h
moVector2
Definition:
moMathVector.h:46
moVector2::UNIT_Y
static const moVector2 UNIT_Y
Definition:
moMathVector.h:393
moVector2::ONE
static const moVector2 ONE
Definition:
moMathVector.h:394
moMathVector.h
moDefineDynamicArray
#define moDefineDynamicArray(name)
Definition:
moArray.cpp:222
moVector2::UNIT_X
static const moVector2 UNIT_X
Definition:
moMathVector.h:392
libmoldeo
moMathVector.cpp
Generado el Martes, 10 de Septiembre de 2019 21:27:07 para libmoldeo (Moldeo 1.0 Core) por
1.8.13