1
// Wild Magic Source Code
3
// http://www.geometrictools.com
4
// Copyright (c) 1998-2007
6
// This library is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License as published by
8
// the Free Software Foundation; either version 2.1 of the License, or (at
9
// your option) any later version. The license is available for reading at
10
// either of the locations:
11
// http://www.gnu.org/copyleft/lgpl.html
12
// http://www.geometrictools.com/License/WildMagicLicense.pdf
13
// The license applies to versions 0 through 4 of Wild Magic.
15
// Version: 4.0.0 (2006/06/28)
17
#include "Wm4FoundationPCH.h"
18
#include "Wm4DistVector3Triangle3.h"
22
//----------------------------------------------------------------------------
24
DistVector3Triangle3<Real>::DistVector3Triangle3 (
25
const Vector3<Real>& rkVector, const Triangle3<Real>& rkTriangle)
28
m_rkTriangle(rkTriangle)
31
//----------------------------------------------------------------------------
33
const Vector3<Real>& DistVector3Triangle3<Real>::GetVector () const
37
//----------------------------------------------------------------------------
39
const Triangle3<Real>& DistVector3Triangle3<Real>::GetTriangle () const
43
//----------------------------------------------------------------------------
45
Real DistVector3Triangle3<Real>::Get ()
47
Real fSqrDist = GetSquared();
48
return Math<Real>::Sqrt(fSqrDist);
50
//----------------------------------------------------------------------------
52
Real DistVector3Triangle3<Real>::GetSquared ()
54
Vector3<Real> kDiff = m_rkTriangle.V[0] - m_rkVector;
55
Vector3<Real> kEdge0 = m_rkTriangle.V[1] - m_rkTriangle.V[0];
56
Vector3<Real> kEdge1 = m_rkTriangle.V[2] - m_rkTriangle.V[0];
57
Real fA00 = kEdge0.SquaredLength();
58
Real fA01 = kEdge0.Dot(kEdge1);
59
Real fA11 = kEdge1.SquaredLength();
60
Real fB0 = kDiff.Dot(kEdge0);
61
Real fB1 = kDiff.Dot(kEdge1);
62
Real fC = kDiff.SquaredLength();
63
Real fDet = Math<Real>::FAbs(fA00*fA11-fA01*fA01);
64
Real fS = fA01*fB1-fA11*fB0;
65
Real fT = fA01*fB0-fA00*fB1;
72
if (fT < (Real)0.0) // region 4
80
fSqrDistance = fA00+((Real)2.0)*fB0+fC;
85
fSqrDistance = fB0*fS+fC;
96
else if (-fB1 >= fA11)
99
fSqrDistance = fA11+((Real)2.0)*fB1+fC;
104
fSqrDistance = fB1*fT+fC;
111
if (fB1 >= (Real)0.0)
116
else if (-fB1 >= fA11)
119
fSqrDistance = fA11+((Real)2.0)*fB1+fC;
124
fSqrDistance = fB1*fT+fC;
128
else if (fT < (Real)0.0) // region 5
131
if (fB0 >= (Real)0.0)
136
else if (-fB0 >= fA00)
139
fSqrDistance = fA00+((Real)2.0)*fB0+fC;
144
fSqrDistance = fB0*fS+fC;
149
// minimum at interior point
150
Real fInvDet = ((Real)1.0)/fDet;
153
fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
154
fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
159
Real fTmp0, fTmp1, fNumer, fDenom;
161
if (fS < (Real)0.0) // region 2
167
fNumer = fTmp1 - fTmp0;
168
fDenom = fA00-2.0f*fA01+fA11;
169
if (fNumer >= fDenom)
173
fSqrDistance = fA00+((Real)2.0)*fB0+fC;
179
fSqrDistance = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
180
fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
186
if (fTmp1 <= (Real)0.0)
189
fSqrDistance = fA11+((Real)2.0)*fB1+fC;
191
else if (fB1 >= (Real)0.0)
199
fSqrDistance = fB1*fT+fC;
203
else if (fT < (Real)0.0) // region 6
209
fNumer = fTmp1 - fTmp0;
210
fDenom = fA00-((Real)2.0)*fA01+fA11;
211
if (fNumer >= fDenom)
215
fSqrDistance = fA11+((Real)2.0)*fB1+fC;
221
fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
222
fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
228
if (fTmp1 <= (Real)0.0)
231
fSqrDistance = fA00+((Real)2.0)*fB0+fC;
233
else if (fB0 >= (Real)0.0)
241
fSqrDistance = fB0*fS+fC;
247
fNumer = fA11 + fB1 - fA01 - fB0;
248
if (fNumer <= (Real)0.0)
252
fSqrDistance = fA11+((Real)2.0)*fB1+fC;
256
fDenom = fA00-2.0f*fA01+fA11;
257
if (fNumer >= fDenom)
261
fSqrDistance = fA00+((Real)2.0)*fB0+fC;
267
fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
268
fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
274
// account for numerical round-off error
275
if (fSqrDistance < (Real)0.0)
277
fSqrDistance = (Real)0.0;
280
m_kClosestPoint0 = m_rkVector;
281
m_kClosestPoint1 = m_rkTriangle.V[0] + fS*kEdge0 + fT*kEdge1;
282
m_afTriangleBary[1] = fS;
283
m_afTriangleBary[2] = fT;
284
m_afTriangleBary[0] = (Real)1.0 - fS - fT;
287
//----------------------------------------------------------------------------
288
template <class Real>
289
Real DistVector3Triangle3<Real>::Get (Real fT,
290
const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
292
Vector3<Real> kMVector = m_rkVector + fT*rkVelocity0;
293
Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
294
Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
295
Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
296
Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
297
return DistVector3Triangle3<Real>(kMVector,kMTriangle).Get();
299
//----------------------------------------------------------------------------
300
template <class Real>
301
Real DistVector3Triangle3<Real>::GetSquared (Real fT,
302
const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
304
Vector3<Real> kMVector = m_rkVector + fT*rkVelocity0;
305
Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
306
Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
307
Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
308
Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
309
return DistVector3Triangle3<Real>(kMVector,kMTriangle).GetSquared();
311
//----------------------------------------------------------------------------
312
template <class Real>
313
Real DistVector3Triangle3<Real>::GetTriangleBary (int i) const
315
assert(0 <= i && i < 3);
316
return m_afTriangleBary[i];
318
//----------------------------------------------------------------------------
320
//----------------------------------------------------------------------------
321
// explicit instantiation
322
//----------------------------------------------------------------------------
323
template WM4_FOUNDATION_ITEM
324
class DistVector3Triangle3<float>;
326
template WM4_FOUNDATION_ITEM
327
class DistVector3Triangle3<double>;
328
//----------------------------------------------------------------------------