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.
moMathVector3.cpp
Ir a la documentación de este archivo.
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
moVector3::ONE
static const moVector3 ONE
Definition:
moMathVector3.h:610
moVector3::UNIT_X
static const moVector3 UNIT_X
Definition:
moMathVector3.h:607
moVector3::UNIT_Y
static const moVector3 UNIT_Y
Definition:
moMathVector3.h:608
moVector3::UNIT_Z
static const moVector3 UNIT_Z
Definition:
moMathVector3.h:609
moDefineDynamicArray
#define moDefineDynamicArray(name)
Definition:
moArray.cpp:222
moVector3::ZERO
static const moVector3 ZERO
Definition:
moMathVector3.h:606
libmoldeo
moMathVector3.cpp
Generado el Martes, 10 de Septiembre de 2019 21:27:07 para libmoldeo (Moldeo 1.0 Core) por
1.8.13