Wm4Triangle3.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <class Real>
00021 Triangle3<Real>::Triangle3 ()
00022 {
00023
00024 }
00025
00026 template <class Real>
00027 Triangle3<Real>::Triangle3 (const Vector3<Real>& rkV0,
00028 const Vector3<Real>& rkV1, const Vector3<Real>& rkV2)
00029 {
00030 V[0] = rkV0;
00031 V[1] = rkV1;
00032 V[2] = rkV2;
00033 }
00034
00035 template <class Real>
00036 Triangle3<Real>::Triangle3 (const Vector3<Real> akV[3])
00037 {
00038 for (int i = 0; i < 3; i++)
00039 {
00040 V[i] = akV[i];
00041 }
00042 }
00043
00044 template <class Real>
00045 Real Triangle3<Real>::DistanceTo (const Vector3<Real>& rkQ) const
00046 {
00047 Vector3<Real> kDiff = V[0] - rkQ;
00048 Vector3<Real> kE0 = V[1] - V[0], kE1 = V[2] - V[0];
00049 Real fA00 = kE0.SquaredLength();
00050 Real fA01 = kE0.Dot(kE1);
00051 Real fA11 = kE1.SquaredLength();
00052 Real fB0 = kDiff.Dot(kE0);
00053 Real fB1 = kDiff.Dot(kE1);
00054 Real fC = kDiff.SquaredLength();
00055 Real fDet = Math<Real>::FAbs(fA00*fA11-fA01*fA01);
00056 Real fS = fA01*fB1-fA11*fB0;
00057 Real fT = fA01*fB0-fA00*fB1;
00058 Real fSqrDist;
00059
00060 if (fS + fT <= fDet)
00061 {
00062 if (fS < (Real)0.0)
00063 {
00064 if (fT < (Real)0.0)
00065 {
00066 if (fB0 < (Real)0.0)
00067 {
00068 if (-fB0 >= fA00)
00069 {
00070 fSqrDist = fA00+((Real)2.0)*fB0+fC;
00071 }
00072 else
00073 {
00074 fSqrDist = fC-fB0*fB0/fA00;
00075 }
00076 }
00077 else
00078 {
00079 if (fB1 >= (Real)0.0)
00080 {
00081 fSqrDist = fC;
00082 }
00083 else if (-fB1 >= fA11)
00084 {
00085 fSqrDist = fA11+((Real)2.0)*fB1+fC;
00086 }
00087 else
00088 {
00089 fSqrDist = fC-fB1*fB1/fA11;
00090 }
00091 }
00092 }
00093 else
00094 {
00095 if (fB1 >= (Real)0.0)
00096 {
00097 fSqrDist = fC;
00098 }
00099 else if (-fB1 >= fA11)
00100 {
00101 fSqrDist = fA11+((Real)2.0)*fB1+fC;
00102 }
00103 else
00104 {
00105 fSqrDist = fC-fB1*fB1/fA11;
00106 }
00107 }
00108 }
00109 else if (fT < (Real)0.0)
00110 {
00111 if (fB0 >= (Real)0.0)
00112 {
00113 fSqrDist = fC;
00114 }
00115 else if (-fB0 >= fA00)
00116 {
00117 fSqrDist = fA00+((Real)2.0)*fB0+fC;
00118 }
00119 else
00120 {
00121 fSqrDist = fC-fB0*fB0/fA00;
00122 }
00123 }
00124 else
00125 {
00126
00127 Real fInvDet = ((Real)1.0)/fDet;
00128 fS *= fInvDet;
00129 fT *= fInvDet;
00130 fSqrDist = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00131 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00132 }
00133 }
00134 else
00135 {
00136 Real fTmp0, fTmp1, fNumer, fDenom;
00137
00138 if (fS < (Real)0.0)
00139 {
00140 fTmp0 = fA01 + fB0;
00141 fTmp1 = fA11 + fB1;
00142 if (fTmp1 > fTmp0)
00143 {
00144 fNumer = fTmp1 - fTmp0;
00145 fDenom = fA00-2.0f*fA01+fA11;
00146 if (fNumer >= fDenom)
00147 {
00148 fSqrDist = fA00+((Real)2.0)*fB0+fC;
00149 }
00150 else
00151 {
00152 fS = fNumer/fDenom;
00153 fT = (Real)1.0 - fS;
00154 fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
00155 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00156 }
00157 }
00158 else
00159 {
00160 if (fTmp1 <= (Real)0.0)
00161 {
00162 fSqrDist = fA11+((Real)2.0)*fB1+fC;
00163 }
00164 else if (fB1 >= (Real)0.0)
00165 {
00166 fSqrDist = fC;
00167 }
00168 else
00169 {
00170 fSqrDist = fC-fB1*fB1/fA11;
00171 }
00172 }
00173 }
00174 else if (fT < (Real)0.0)
00175 {
00176 fTmp0 = fA01 + fB1;
00177 fTmp1 = fA00 + fB0;
00178 if (fTmp1 > fTmp0)
00179 {
00180 fNumer = fTmp1 - fTmp0;
00181 fDenom = fA00-((Real)2.0)*fA01+fA11;
00182 if (fNumer >= fDenom)
00183 {
00184 fT = (Real)1.0;
00185 fS = (Real)0.0;
00186 fSqrDist = fA11+((Real)2.0)*fB1+fC;
00187 }
00188 else
00189 {
00190 fT = fNumer/fDenom;
00191 fS = (Real)1.0 - fT;
00192 fSqrDist = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00193 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00194 }
00195 }
00196 else
00197 {
00198 if (fTmp1 <= (Real)0.0)
00199 {
00200 fSqrDist = fA00+((Real)2.0)*fB0+fC;
00201 }
00202 else if (fB0 >= (Real)0.0)
00203 {
00204 fSqrDist = fC;
00205 }
00206 else
00207 {
00208 fSqrDist = fC-fB0*fB0/fA00;
00209 }
00210 }
00211 }
00212 else
00213 {
00214 fNumer = fA11 + fB1 - fA01 - fB0;
00215 if (fNumer <= (Real)0.0)
00216 {
00217 fSqrDist = fA11+((Real)2.0)*fB1+fC;
00218 }
00219 else
00220 {
00221 fDenom = fA00-2.0f*fA01+fA11;
00222 if (fNumer >= fDenom)
00223 {
00224 fSqrDist = fA00+((Real)2.0)*fB0+fC;
00225 }
00226 else
00227 {
00228 fS = fNumer/fDenom;
00229 fT = (Real)1.0 - fS;
00230 fSqrDist = fS*(fA00*fS+fA01*fT+((Real)2.0)*fB0) +
00231 fT*(fA01*fS+fA11*fT+((Real)2.0)*fB1)+fC;
00232 }
00233 }
00234 }
00235 }
00236
00237 return Math<Real>::Sqrt(Math<Real>::FAbs(fSqrDist));
00238 }
00239
00240 }