Wm4Triangle3.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 namespace Wm4
00018 {
00019 //----------------------------------------------------------------------------
00020 template <class Real>
00021 Triangle3<Real>::Triangle3 ()
00022 {
00023     // uninitialized
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)  // region 4
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  // region 3
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)  // region 5
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  // region 0
00125         {
00126             // minimum at interior point
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)  // region 2
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)  // region 6
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  // region 1
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 } //namespace Wm4

Generated on Wed Nov 23 19:01:10 2011 for FreeCAD by  doxygen 1.6.1