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
moMathVector3.cpp
Go to the documentation of this file.
1
/*******************************************************************************
2
3
moMathVector3.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 "
moMathVector3.h
"
39
40
#include "
moArray.h
"
41
moDefineDynamicArray
(moVector3iArray)
42
moDefineDynamicArray
(moVector3fArray)
43
moDefineDynamicArray
(moVector3dArray)
44
45
// moVector3 class ------------------------------------------------------------
46
/*
47
template <class Real>
48
moVector3<Real>::moVector3 ()
49
{
50
// uninitialized for performance in array construction
51
}
52
53
template <class Real>
54
moVector3<Real>::moVector3 (Real fX, Real fY, Real fZ)
55
{
56
m_afTuple[0] = fX;
57
m_afTuple[1] = fY;
58
m_afTuple[2] = fZ;
59
}
60
61
template <class Real>
62
moVector3<Real>::moVector3 (const Real* afTuple)
63
{
64
m_afTuple[0] = afTuple[0];
65
m_afTuple[1] = afTuple[1];
66
m_afTuple[2] = afTuple[2];
67
}
68
*/
69
/*
70
template <class Real>
71
moVector3<Real>::moVector3 (const moVector3& rkV) : moAbstract(rkV)
72
{
73
m_afTuple[0] = rkV.m_afTuple[0];
74
m_afTuple[1] = rkV.m_afTuple[1];
75
m_afTuple[2] = rkV.m_afTuple[2];
76
}
77
78
template <class Real>
79
int moVector3<Real>::CompareArrays (const moVector3& rkV) const
80
{
81
return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(Real));
82
}
83
84
template <class Real>
85
bool moVector3<Real>::operator== (const moVector3& rkV) const
86
{
87
return CompareArrays(rkV) == 0;
88
}
89
90
template <class Real>
91
bool moVector3<Real>::operator!= (const moVector3& rkV) const
92
{
93
return CompareArrays(rkV) != 0;
94
}
95
96
template <class Real>
97
bool moVector3<Real>::operator< (const moVector3& rkV) const
98
{
99
return CompareArrays(rkV) < 0;
100
}
101
102
template <class Real>
103
bool moVector3<Real>::operator<= (const moVector3& rkV) const
104
{
105
return CompareArrays(rkV) <= 0;
106
}
107
108
template <class Real>
109
bool moVector3<Real>::operator> (const moVector3& rkV) const
110
{
111
return CompareArrays(rkV) > 0;
112
}
113
114
template <class Real>
115
bool moVector3<Real>::operator>= (const moVector3& rkV) const
116
{
117
return CompareArrays(rkV) >= 0;
118
}
119
120
template <class Real>
121
void moVector3<Real>::GetBarycentrics (const moVector3<Real>& rkV0,
122
const moVector3<Real>& rkV1, const moVector3<Real>& rkV2,
123
const moVector3<Real>& rkV3, Real afBary[4]) const
124
{
125
// compute the vectors relative to V3 of the tetrahedron
126
moVector3<Real> akDiff[4] =
127
{
128
rkV0 - rkV3,
129
rkV1 - rkV3,
130
rkV2 - rkV3,
131
*this - rkV3
132
};
133
134
// If the vertices have large magnitude, the linear system of
135
// equations for computing barycentric coordinates can be
136
// ill-conditioned. To avoid this, uniformly scale the tetrahedron
137
// edges to be of order 1. The scaling of all differences does not
138
// change the barycentric coordinates.
139
Real fMax = (Real)0.0;
140
int i;
141
for (i = 0; i < 3; i++)
142
{
143
for (int j = 0; j < 3; j++)
144
{
145
Real fValue = moMath<Real>::FAbs(akDiff[i][j]);
146
if (fValue > fMax)
147
{
148
fMax = fValue;
149
}
150
}
151
}
152
153
// scale down only large data
154
if (fMax > (Real)1.0)
155
{
156
Real fInvMax = ((Real)1.0)/fMax;
157
for (i = 0; i < 4; i++)
158
{
159
akDiff[i] *= fInvMax;
160
}
161
}
162
163
Real fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
164
moVector3<Real> kE1cE2 = akDiff[1].Cross(akDiff[2]);
165
moVector3<Real> kE2cE0 = akDiff[2].Cross(akDiff[0]);
166
moVector3<Real> kE0cE1 = akDiff[0].Cross(akDiff[1]);
167
if (moMath<Real>::FAbs(fDet) > moMath<Real>::ZERO_TOLERANCE)
168
{
169
Real fInvDet = ((Real)1.0)/fDet;
170
afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
171
afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
172
afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
173
afBary[3] = (Real)1.0 - afBary[0] - afBary[1] - afBary[2];
174
}
175
else
176
{
177
// The tetrahedron is potentially flat. Determine the face of
178
// maximum area and compute barycentric coordinates with respect
179
// to that face.
180
moVector3<Real> kE02 = rkV0 - rkV2;
181
moVector3<Real> kE12 = rkV1 - rkV2;
182
moVector3<Real> kE02cE12 = kE02.Cross(kE12);
183
Real fMaxSqrArea = kE02cE12.SquaredLength();
184
int iMaxIndex = 3;
185
Real fSqrArea = kE0cE1.SquaredLength();
186
if (fSqrArea > fMaxSqrArea)
187
{
188
iMaxIndex = 0;
189
fMaxSqrArea = fSqrArea;
190
}
191
fSqrArea = kE1cE2.SquaredLength();
192
if (fSqrArea > fMaxSqrArea)
193
{
194
iMaxIndex = 1;
195
fMaxSqrArea = fSqrArea;
196
}
197
fSqrArea = kE2cE0.SquaredLength();
198
if (fSqrArea > fMaxSqrArea)
199
{
200
iMaxIndex = 2;
201
fMaxSqrArea = fSqrArea;
202
}
203
204
if (fMaxSqrArea > moMath<Real>::ZERO_TOLERANCE)
205
{
206
Real fInvSqrArea = ((Real)1.0)/fMaxSqrArea;
207
moVector3<Real> kTmp;
208
if (iMaxIndex == 0)
209
{
210
kTmp = akDiff[3].Cross(akDiff[1]);
211
afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
212
kTmp = akDiff[0].Cross(akDiff[3]);
213
afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
214
afBary[2] = (Real)0.0;
215
afBary[3] = (Real)1.0 - afBary[0] - afBary[1];
216
}
217
else if (iMaxIndex == 1)
218
{
219
afBary[0] = (Real)0.0;
220
kTmp = akDiff[3].Cross(akDiff[2]);
221
afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
222
kTmp = akDiff[1].Cross(akDiff[3]);
223
afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
224
afBary[3] = (Real)1.0 - afBary[1] - afBary[2];
225
}
226
else if (iMaxIndex == 2)
227
{
228
kTmp = akDiff[2].Cross(akDiff[3]);
229
afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
230
afBary[1] = (Real)0.0;
231
kTmp = akDiff[3].Cross(akDiff[0]);
232
afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
233
afBary[3] = (Real)1.0 - afBary[0] - afBary[2];
234
}
235
else
236
{
237
akDiff[3] = *this - rkV2;
238
kTmp = akDiff[3].Cross(kE12);
239
afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
240
kTmp = kE02.Cross(akDiff[3]);
241
afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
242
afBary[2] = (Real)1.0 - afBary[0] - afBary[1];
243
afBary[3] = (Real)0.0;
244
}
245
}
246
else
247
{
248
// The tetrahedron is potentially a sliver. Determine the edge of
249
// maximum length and compute barycentric coordinates with respect
250
// to that edge.
251
Real fMaxSqrLength = akDiff[0].SquaredLength();
252
iMaxIndex = 0; // <V0,V3>
253
Real fSqrLength = akDiff[1].SquaredLength();
254
if (fSqrLength > fMaxSqrLength)
255
{
256
iMaxIndex = 1; // <V1,V3>
257
fMaxSqrLength = fSqrLength;
258
}
259
fSqrLength = akDiff[2].SquaredLength();
260
if (fSqrLength > fMaxSqrLength)
261
{
262
iMaxIndex = 2; // <V2,V3>
263
fMaxSqrLength = fSqrLength;
264
}
265
fSqrLength = kE02.SquaredLength();
266
if (fSqrLength > fMaxSqrLength)
267
{
268
iMaxIndex = 3; // <V0,V2>
269
fMaxSqrLength = fSqrLength;
270
}
271
fSqrLength = kE12.SquaredLength();
272
if (fSqrLength > fMaxSqrLength)
273
{
274
iMaxIndex = 4; // <V1,V2>
275
fMaxSqrLength = fSqrLength;
276
}
277
moVector3<Real> kE01 = rkV0 - rkV1;
278
fSqrLength = kE01.SquaredLength();
279
if (fSqrLength > fMaxSqrLength)
280
{
281
iMaxIndex = 5; // <V0,V1>
282
fMaxSqrLength = fSqrLength;
283
}
284
285
if (fMaxSqrLength > moMath<Real>::ZERO_TOLERANCE)
286
{
287
Real fInvSqrLength = ((Real)1.0)/fMaxSqrLength;
288
if (iMaxIndex == 0)
289
{
290
// P-V3 = t*(V0-V3)
291
afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
292
afBary[1] = (Real)0.0;
293
afBary[2] = (Real)0.0;
294
afBary[3] = (Real)1.0 - afBary[0];
295
}
296
else if (iMaxIndex == 1)
297
{
298
// P-V3 = t*(V1-V3)
299
afBary[0] = (Real)0.0;
300
afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
301
afBary[2] = (Real)0.0;
302
afBary[3] = (Real)1.0 - afBary[1];
303
}
304
else if (iMaxIndex == 2)
305
{
306
// P-V3 = t*(V2-V3)
307
afBary[0] = (Real)0.0;
308
afBary[1] = (Real)0.0;
309
afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
310
afBary[3] = (Real)1.0 - afBary[2];
311
}
312
else if (iMaxIndex == 3)
313
{
314
// P-V2 = t*(V0-V2)
315
akDiff[3] = *this - rkV2;
316
afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
317
afBary[1] = (Real)0.0;
318
afBary[2] = (Real)1.0 - afBary[0];
319
afBary[3] = (Real)0.0;
320
}
321
else if (iMaxIndex == 4)
322
{
323
// P-V2 = t*(V1-V2)
324
akDiff[3] = *this - rkV2;
325
afBary[0] = (Real)0.0;
326
afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
327
afBary[2] = (Real)1.0 - afBary[1];
328
afBary[3] = (Real)0.0;
329
}
330
else
331
{
332
// P-V1 = t*(V0-V1)
333
akDiff[3] = *this - rkV1;
334
afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
335
afBary[1] = (Real)1.0 - afBary[0];
336
afBary[2] = (Real)0.0;
337
afBary[3] = (Real)0.0;
338
}
339
}
340
else
341
{
342
// tetrahedron is a nearly a point, just return equal weights
343
afBary[0] = (Real)0.25;
344
afBary[1] = afBary[0];
345
afBary[2] = afBary[0];
346
afBary[3] = afBary[0];
347
}
348
}
349
}
350
}
351
352
template <class Real>
353
void moVector3<Real>::Orthonormalize (moVector3& rkU, moVector3& rkV, moVector3& rkW)
354
{
355
// If the input vectors are v0, v1, and v2, then the Gram-Schmidt
356
// orthonormalization produces vectors u0, u1, and u2 as follows,
357
//
358
// u0 = v0/|v0|
359
// u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
360
// u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
361
//
362
// where |A| indicates length of vector A and A*B indicates dot
363
// product of vectors A and B.
364
365
// compute u0
366
rkU.Normalize();
367
368
// compute u1
369
Real fDot0 = rkU.Dot(rkV);
370
rkV -= fDot0*rkU;
371
rkV.Normalize();
372
373
// compute u2
374
Real fDot1 = rkV.Dot(rkW);
375
fDot0 = rkU.Dot(rkW);
376
rkW -= fDot0*rkU + fDot1*rkV;
377
rkW.Normalize();
378
}
379
380
template <class Real>
381
void moVector3<Real>::Orthonormalize (moVector3* akV)
382
{
383
Orthonormalize(akV[0],akV[1],akV[2]);
384
}
385
386
template <class Real>
387
void moVector3<Real>::GenerateOrthonormalBasis (moVector3& rkU, moVector3& rkV,
388
moVector3& rkW)
389
{
390
rkW.Normalize();
391
GenerateComplementBasis(rkU,rkV,rkW);
392
}
393
394
template <class Real>
395
void moVector3<Real>::GenerateComplementBasis (moVector3& rkU, moVector3& rkV,
396
const moVector3& rkW)
397
{
398
Real fInvLength;
399
400
if (moMath<Real>::FAbs(rkW.m_afTuple[0]) >=
401
moMath<Real>::FAbs(rkW.m_afTuple[1]) )
402
{
403
// W.x or W.z is the largest magnitude component, swap them
404
fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] +
405
rkW.m_afTuple[2]*rkW.m_afTuple[2]);
406
rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
407
rkU.m_afTuple[1] = (Real)0.0;
408
rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
409
rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2];
410
rkV.m_afTuple[1] = rkW.m_afTuple[2]*rkU.m_afTuple[0] -
411
rkW.m_afTuple[0]*rkU.m_afTuple[2];
412
rkV.m_afTuple[2] = -rkW.m_afTuple[1]*rkU.m_afTuple[0];
413
}
414
else
415
{
416
// W.y or W.z is the largest magnitude component, swap them
417
fInvLength = moMath<Real>::InvSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] +
418
rkW.m_afTuple[2]*rkW.m_afTuple[2]);
419
rkU.m_afTuple[0] = (Real)0.0;
420
rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
421
rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
422
rkV.m_afTuple[0] = rkW.m_afTuple[1]*rkU.m_afTuple[2] -
423
rkW.m_afTuple[2]*rkU.m_afTuple[1];
424
rkV.m_afTuple[1] = -rkW.m_afTuple[0]*rkU.m_afTuple[2];
425
rkV.m_afTuple[2] = rkW.m_afTuple[0]*rkU.m_afTuple[1];
426
}
427
}
428
429
template <class Real>
430
void moVector3<Real>::ComputeExtremes (int iVQuantity, const moVector3* akPoint,
431
moVector3& rkMin, moVector3& rkMax)
432
{
433
if (!(iVQuantity > 0 && akPoint)) return;
434
435
rkMin = akPoint[0];
436
rkMax = rkMin;
437
for (int i = 1; i < iVQuantity; i++)
438
{
439
const moVector3<Real>& rkPoint = akPoint[i];
440
for (int j = 0; j < 3; j++)
441
{
442
if (rkPoint[j] < rkMin[j])
443
{
444
rkMin[j] = rkPoint[j];
445
}
446
else if (rkPoint[j] > rkMax[j])
447
{
448
rkMax[j] = rkPoint[j];
449
}
450
}
451
}
452
}
453
454
455
// arithmetic operations
456
template <class Real>
457
moVector3<Real> moVector3<Real>::operator+ (const moVector3& rkV) const
458
{
459
moVector3<Real> ret(m_afTuple[0]+rkV.m_afTuple[0], m_afTuple[1]+rkV.m_afTuple[1], m_afTuple[2]+rkV.m_afTuple[2]);
460
return ret;
461
}
462
463
464
template <class Real>
465
moVector3<Real> moVector3<Real>::operator- (const moVector3& rkV) const
466
{
467
return moVector3<Real>(m_afTuple[0]-rkV.m_afTuple[0],m_afTuple[1]-rkV.m_afTuple[1],m_afTuple[2]-rkV.m_afTuple[2]);
468
}
469
470
471
template <class Real>
472
moVector3<Real> moVector3<Real>::operator* (Real fScalar) const
473
{
474
return moVector3<Real>(
475
fScalar*m_afTuple[0],
476
fScalar*m_afTuple[1],
477
fScalar*m_afTuple[2]);
478
}
479
480
481
template <class Real>
482
moVector3<Real> moVector3<Real>::operator/ (Real fScalar) const
483
{
484
moVector3<Real> kQuot;
485
486
if (fScalar != (Real)0.0)
487
{
488
Real fInvScalar = ((Real)1.0)/fScalar;
489
kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
490
kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
491
kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
492
}
493
else
494
{
495
kQuot.m_afTuple[0] = moMath<Real>::MAX_REAL;
496
kQuot.m_afTuple[1] = moMath<Real>::MAX_REAL;
497
kQuot.m_afTuple[2] = moMath<Real>::MAX_REAL;
498
}
499
500
return kQuot;
501
}
502
template <class Real>
503
moVector3<Real> moVector3<Real>::operator- () const
504
{
505
return moVector3<Real>(-m_afTuple[0], -m_afTuple[1], -m_afTuple[2]);
506
}
507
508
// arithmetic updates
509
template <class Real>
510
moVector3<Real>& moVector3<Real>::operator+= (const moVector3& rkV)
511
{
512
m_afTuple[0] += rkV.m_afTuple[0];
513
m_afTuple[1] += rkV.m_afTuple[1];
514
m_afTuple[2] += rkV.m_afTuple[2];
515
return *this;
516
}
517
template <class Real>
518
moVector3<Real>& moVector3<Real>::operator-= (const moVector3& rkV)
519
{
520
m_afTuple[0] -= rkV.m_afTuple[0];
521
m_afTuple[1] -= rkV.m_afTuple[1];
522
m_afTuple[2] -= rkV.m_afTuple[2];
523
return *this;
524
}
525
template <class Real>
526
moVector3<Real>& moVector3<Real>::operator*= (const Real fScalar)
527
{
528
m_afTuple[0] *= fScalar;
529
m_afTuple[1] *= fScalar;
530
m_afTuple[2] *= fScalar;
531
return *this;
532
}
533
template <class Real>
534
moVector3<Real>& moVector3<Real>::operator/= (const Real fScalar)
535
{
536
if (fScalar != (Real)0.0)
537
{
538
Real fInvScalar = ((Real)1.0)/fScalar;
539
m_afTuple[0] *= fInvScalar;
540
m_afTuple[1] *= fInvScalar;
541
m_afTuple[2] *= fInvScalar;
542
}
543
else
544
{
545
m_afTuple[0] = moMath<Real>::MAX_REAL;
546
m_afTuple[1] = moMath<Real>::MAX_REAL;
547
m_afTuple[2] = moMath<Real>::MAX_REAL;
548
}
549
550
return *this;
551
}
552
*/
553
/*
554
// vector operations
555
template <class Real>
556
Real moVector3<Real>::Length () const
557
{
558
return moMath<Real>::Sqrt(
559
m_afTuple[0]*m_afTuple[0] +
560
m_afTuple[1]*m_afTuple[1] +
561
m_afTuple[2]*m_afTuple[2]);
562
}
563
564
565
template <class Real>
566
Real moVector3<Real>::SquaredLength () const
567
{
568
return
569
m_afTuple[0]*m_afTuple[0] +
570
m_afTuple[1]*m_afTuple[1] +
571
m_afTuple[2]*m_afTuple[2];
572
}
573
template <class Real>
574
Real moVector3<Real>::Dot (const moVector3& rkV) const
575
{
576
return
577
m_afTuple[0]*rkV.m_afTuple[0] +
578
m_afTuple[1]*rkV.m_afTuple[1] +
579
m_afTuple[2]*rkV.m_afTuple[2];
580
}
581
582
583
template <class Real>
584
Real moVector3<Real>::Normalize ()
585
{
586
Real fLength = Length();
587
588
if (fLength > moMath<Real>::ZERO_TOLERANCE)
589
{
590
Real fInvLength = ((Real)1.0)/fLength;
591
m_afTuple[0] *= fInvLength;
592
m_afTuple[1] *= fInvLength;
593
m_afTuple[2] *= fInvLength;
594
}
595
else
596
{
597
fLength = (Real)0.0;
598
m_afTuple[0] = (Real)0.0;
599
m_afTuple[1] = (Real)0.0;
600
m_afTuple[2] = (Real)0.0;
601
}
602
603
return fLength;
604
}
605
606
// The cross products are computed using the right-handed rule. Be aware
607
// that some graphics APIs use a left-handed rule. If you have to compute
608
// a cross product with these functions and send the result to the API
609
// that expects left-handed, you will need to change sign on the vector
610
// (replace each component value c by -c).
611
612
template <class Real>
613
moVector3<Real> moVector3<Real>::Cross (const moVector3& rkV) const
614
{
615
moVector3<Real> kCross(
616
m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
617
m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
618
m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
619
return kCross;
620
}
621
622
template <class Real>
623
moVector3<Real> moVector3<Real>::UnitCross (const moVector3& rkV) const
624
{
625
moVector3<Real> kCross(
626
m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
627
m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
628
m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
629
kCross.Normalize();
630
return kCross;
631
}
632
633
634
// Cosine between 'this' vector and rkV.
635
template <class Real>
636
Real moVector3<Real>::Cosine (const moVector3<Real>& rkV)
637
{
638
Real l = Length();
639
Real lv = rkV.Length();
640
if ((0 < l) && (0 < lv)) return Dot(rkV) / (l * lv);
641
else return 0;
642
}
643
// Angle between 'this' vector and rkV.
644
template <class Real>
645
Real moVector3<Real>::Angle (const moVector3<Real>& rkV) {
646
return moMath<Real>::ACos(Cosine(rkV));
647
}
648
*/
649
template<> const
moVector3
<
MOlong
>
moVector3
<
MOlong
>::ZERO(0,0,0);
650
template<> const
moVector3
<
MOlong
>
moVector3
<
MOlong
>::UNIT_X(1,0,0);
651
template<> const
moVector3
<
MOlong
>
moVector3
<
MOlong
>::UNIT_Y(0,1,0);
652
template<> const
moVector3
<
MOlong
>
moVector3
<
MOlong
>::UNIT_Z(0,0,1);
653
template<> const
moVector3
<
MOlong
>
moVector3
<
MOlong
>::ONE(1,1,1);
654
655
template<> const
moVector3
<
MOfloat
>
moVector3
<
MOfloat
>::ZERO(0.0f,0.0f,0.0f);
656
template<> const
moVector3
<
MOfloat
>
moVector3
<
MOfloat
>::UNIT_X(1.0f,0.0f,0.0f);
657
template<> const
moVector3
<
MOfloat
>
moVector3
<
MOfloat
>::UNIT_Y(0.0f,1.0f,0.0f);
658
template<> const
moVector3
<
MOfloat
>
moVector3
<
MOfloat
>::UNIT_Z(0.0f,0.0f,1.0f);
659
template<> const
moVector3
<
MOfloat
>
moVector3
<
MOfloat
>::ONE(1.0f,1.0f,1.0f);
660
661
template<> const
moVector3
<
MOdouble
>
moVector3
<
MOdouble
>::ZERO(0.0,0.0,0.0);
662
template<> const
moVector3
<
MOdouble
>
moVector3
<
MOdouble
>::UNIT_X(1.0,0.0,0.0);
663
template<> const
moVector3
<
MOdouble
>
moVector3
<
MOdouble
>::UNIT_Y(0.0,1.0,0.0);
664
template<> const
moVector3
<
MOdouble
>
moVector3
<
MOdouble
>::UNIT_Z(0.0,0.0,1.0);
665
template<> const
moVector3
<
MOdouble
>
moVector3
<
MOdouble
>::ONE(1.0,1.0,1.0);
666
667
moArray.h
moMathVector3.h
moVector3
Definition:
moMathVector3.h:46
MOfloat
#define MOfloat
Definition:
moTypes.h:403
MOlong
#define MOlong
Definition:
moTypes.h:391
moDefineDynamicArray
#define moDefineDynamicArray(name)
Definition:
moArray.cpp:222
MOdouble
#define MOdouble
Definition:
moTypes.h:404
libmoldeo
moMathVector3.cpp
Generated on Wed May 17 2017 14:09:18 for libmoldeo (Moldeo 1.0 Core) by
1.8.8