Wm4DistVector3Triangle3.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4DistVector3Triangle3.h"
00019
00020 namespace Wm4
00021 {
00022
00023 template <class Real>
00024 DistVector3Triangle3<Real>::DistVector3Triangle3 (
00025 const Vector3<Real>& rkVector, const Triangle3<Real>& rkTriangle)
00026 :
00027 m_rkVector(rkVector),
00028 m_rkTriangle(rkTriangle)
00029 {
00030 }
00031
00032 template <class Real>
00033 const Vector3<Real>& DistVector3Triangle3<Real>::GetVector () const
00034 {
00035 return m_rkVector;
00036 }
00037
00038 template <class Real>
00039 const Triangle3<Real>& DistVector3Triangle3<Real>::GetTriangle () const
00040 {
00041 return m_rkTriangle;
00042 }
00043
00044 template <class Real>
00045 Real DistVector3Triangle3<Real>::Get ()
00046 {
00047 Real fSqrDist = GetSquared();
00048 return Math<Real>::Sqrt(fSqrDist);
00049 }
00050
00051 template <class Real>
00052 Real DistVector3Triangle3<Real>::GetSquared ()
00053 {
00054 Vector3<Real> kDiff = m_rkTriangle.V[0] - m_rkVector;
00055 Vector3<Real> kEdge0 = m_rkTriangle.V[1] - m_rkTriangle.V[0];
00056 Vector3<Real> kEdge1 = m_rkTriangle.V[2] - m_rkTriangle.V[0];
00057 Real fA00 = kEdge0.SquaredLength();
00058 Real fA01 = kEdge0.Dot(kEdge1);
00059 Real fA11 = kEdge1.SquaredLength();
00060 Real fB0 = kDiff.Dot(kEdge0);
00061 Real fB1 = kDiff.Dot(kEdge1);
00062 Real fC = kDiff.SquaredLength();
00063 Real fDet = Math<Real>::FAbs(fA00*fA11-fA01*fA01);
00064 Real fS = fA01*fB1-fA11*fB0;
00065 Real fT = fA01*fB0-fA00*fB1;
00066 Real fSqrDistance;
00067
00068 if (fS + fT <= fDet)
00069 {
00070 if (fS < (Real)0.0)
00071 {
00072 if (fT < (Real)0.0)
00073 {
00074 if (fB0 < (Real)0.0)
00075 {
00076 fT = (Real)0.0;
00077 if (-fB0 >= fA00)
00078 {
00079 fS = (Real)1.0;
00080 fSqrDistance = fA00+((Real)2.0)*fB0+fC;
00081 }
00082 else
00083 {
00084 fS = -fB0/fA00;
00085 fSqrDistance = fB0*fS+fC;
00086 }
00087 }
00088 else
00089 {
00090 fS = (Real)0.0;
00091 if (fB1 >= (Real)0.0)
00092 {
00093 fT = (Real)0.0;
00094 fSqrDistance = fC;
00095 }
00096 else if (-fB1 >= fA11)
00097 {
00098 fT = (Real)1.0;
00099 fSqrDistance = fA11+((Real)2.0)*fB1+fC;
00100 }
00101 else
00102 {
00103 fT = -fB1/fA11;
00104 fSqrDistance = fB1*fT+fC;
00105 }
00106 }
00107 }
00108 else
00109 {
00110 fS = (Real)0.0;
00111 if (fB1 >= (Real)0.0)
00112 {
00113 fT = (Real)0.0;
00114 fSqrDistance = fC;
00115 }
00116 else if (-fB1 >= fA11)
00117 {
00118 fT = (Real)1.0;
00119 fSqrDistance = fA11+((Real)2.0)*fB1+fC;
00120 }
00121 else
00122 {
00123 fT = -fB1/fA11;
00124 fSqrDistance = fB1*fT+fC;
00125 }
00126 }
00127 }
00128 else if (fT < (Real)0.0)
00129 {
00130 fT = (Real)0.0;
00131 if (fB0 >= (Real)0.0)
00132 {
00133 fS = (Real)0.0;
00134 fSqrDistance = fC;
00135 }
00136 else if (-fB0 >= fA00)
00137 {
00138 fS = (Real)1.0;
00139 fSqrDistance = fA00+((Real)2.0)*fB0+fC;
00140 }
00141 else
00142 {
00143 fS = -fB0/fA00;
00144 fSqrDistance = fB0*fS+fC;
00145 }
00146 }
00147 else
00148 {
00149
00150 Real fInvDet = ((Real)1.0)/fDet;
00151 fS *= fInvDet;
00152 fT *= fInvDet;
00153 fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00154 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00155 }
00156 }
00157 else
00158 {
00159 Real fTmp0, fTmp1, fNumer, fDenom;
00160
00161 if (fS < (Real)0.0)
00162 {
00163 fTmp0 = fA01 + fB0;
00164 fTmp1 = fA11 + fB1;
00165 if (fTmp1 > fTmp0)
00166 {
00167 fNumer = fTmp1 - fTmp0;
00168 fDenom = fA00-2.0f*fA01+fA11;
00169 if (fNumer >= fDenom)
00170 {
00171 fS = (Real)1.0;
00172 fT = (Real)0.0;
00173 fSqrDistance = fA00+((Real)2.0)*fB0+fC;
00174 }
00175 else
00176 {
00177 fS = fNumer/fDenom;
00178 fT = (Real)1.0 - fS;
00179 fSqrDistance = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
00180 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00181 }
00182 }
00183 else
00184 {
00185 fS = (Real)0.0;
00186 if (fTmp1 <= (Real)0.0)
00187 {
00188 fT = (Real)1.0;
00189 fSqrDistance = fA11+((Real)2.0)*fB1+fC;
00190 }
00191 else if (fB1 >= (Real)0.0)
00192 {
00193 fT = (Real)0.0;
00194 fSqrDistance = fC;
00195 }
00196 else
00197 {
00198 fT = -fB1/fA11;
00199 fSqrDistance = fB1*fT+fC;
00200 }
00201 }
00202 }
00203 else if (fT < (Real)0.0)
00204 {
00205 fTmp0 = fA01 + fB1;
00206 fTmp1 = fA00 + fB0;
00207 if (fTmp1 > fTmp0)
00208 {
00209 fNumer = fTmp1 - fTmp0;
00210 fDenom = fA00-((Real)2.0)*fA01+fA11;
00211 if (fNumer >= fDenom)
00212 {
00213 fT = (Real)1.0;
00214 fS = (Real)0.0;
00215 fSqrDistance = fA11+((Real)2.0)*fB1+fC;
00216 }
00217 else
00218 {
00219 fT = fNumer/fDenom;
00220 fS = (Real)1.0 - fT;
00221 fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00222 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00223 }
00224 }
00225 else
00226 {
00227 fT = (Real)0.0;
00228 if (fTmp1 <= (Real)0.0)
00229 {
00230 fS = (Real)1.0;
00231 fSqrDistance = fA00+((Real)2.0)*fB0+fC;
00232 }
00233 else if (fB0 >= (Real)0.0)
00234 {
00235 fS = (Real)0.0;
00236 fSqrDistance = fC;
00237 }
00238 else
00239 {
00240 fS = -fB0/fA00;
00241 fSqrDistance = fB0*fS+fC;
00242 }
00243 }
00244 }
00245 else
00246 {
00247 fNumer = fA11 + fB1 - fA01 - fB0;
00248 if (fNumer <= (Real)0.0)
00249 {
00250 fS = (Real)0.0;
00251 fT = (Real)1.0;
00252 fSqrDistance = fA11+((Real)2.0)*fB1+fC;
00253 }
00254 else
00255 {
00256 fDenom = fA00-2.0f*fA01+fA11;
00257 if (fNumer >= fDenom)
00258 {
00259 fS = (Real)1.0;
00260 fT = (Real)0.0;
00261 fSqrDistance = fA00+((Real)2.0)*fB0+fC;
00262 }
00263 else
00264 {
00265 fS = fNumer/fDenom;
00266 fT = (Real)1.0 - fS;
00267 fSqrDistance = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00268 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00269 }
00270 }
00271 }
00272 }
00273
00274
00275 if (fSqrDistance < (Real)0.0)
00276 {
00277 fSqrDistance = (Real)0.0;
00278 }
00279
00280 m_kClosestPoint0 = m_rkVector;
00281 m_kClosestPoint1 = m_rkTriangle.V[0] + fS*kEdge0 + fT*kEdge1;
00282 m_afTriangleBary[1] = fS;
00283 m_afTriangleBary[2] = fT;
00284 m_afTriangleBary[0] = (Real)1.0 - fS - fT;
00285 return fSqrDistance;
00286 }
00287
00288 template <class Real>
00289 Real DistVector3Triangle3<Real>::Get (Real fT,
00290 const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
00291 {
00292 Vector3<Real> kMVector = m_rkVector + fT*rkVelocity0;
00293 Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
00294 Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
00295 Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
00296 Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
00297 return DistVector3Triangle3<Real>(kMVector,kMTriangle).Get();
00298 }
00299
00300 template <class Real>
00301 Real DistVector3Triangle3<Real>::GetSquared (Real fT,
00302 const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
00303 {
00304 Vector3<Real> kMVector = m_rkVector + fT*rkVelocity0;
00305 Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
00306 Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
00307 Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
00308 Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
00309 return DistVector3Triangle3<Real>(kMVector,kMTriangle).GetSquared();
00310 }
00311
00312 template <class Real>
00313 Real DistVector3Triangle3<Real>::GetTriangleBary (int i) const
00314 {
00315 assert(0 <= i && i < 3);
00316 return m_afTriangleBary[i];
00317 }
00318
00319
00320
00321
00322
00323 template WM4_FOUNDATION_ITEM
00324 class DistVector3Triangle3<float>;
00325
00326 template WM4_FOUNDATION_ITEM
00327 class DistVector3Triangle3<double>;
00328
00329 }