Wm4ImplicitSurface.cpp

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.1 (2006/07/23)
00016 
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4ImplicitSurface.h"
00019 
00020 namespace Wm4
00021 {
00022 //----------------------------------------------------------------------------
00023 template <class Real>
00024 ImplicitSurface<Real>::ImplicitSurface ()
00025 {
00026 }
00027 //----------------------------------------------------------------------------
00028 template <class Real>
00029 ImplicitSurface<Real>::~ImplicitSurface ()
00030 {
00031 }
00032 //----------------------------------------------------------------------------
00033 template <class Real>
00034 bool ImplicitSurface<Real>::IsOnSurface (const Vector3<Real>& rkP,
00035     Real fEpsilon) const
00036 {
00037     return Math<Real>::FAbs(F(rkP)) <= fEpsilon;
00038 }
00039 //----------------------------------------------------------------------------
00040 template <class Real>
00041 Vector3<Real> ImplicitSurface<Real>::GetGradient (const Vector3<Real>& rkP)
00042     const
00043 {
00044     Real fFX = FX(rkP);
00045     Real fFY = FY(rkP);
00046     Real fFZ = FZ(rkP);
00047     return Vector3<Real>(fFX,fFY,fFZ);
00048 }
00049 //----------------------------------------------------------------------------
00050 template <class Real>
00051 Matrix3<Real> ImplicitSurface<Real>::GetHessian (const Vector3<Real>& rkP)
00052     const
00053 {
00054     Real fFXX = FXX(rkP);
00055     Real fFXY = FXY(rkP);
00056     Real fFXZ = FXZ(rkP);
00057     Real fFYY = FYY(rkP);
00058     Real fFYZ = FYZ(rkP);
00059     Real fFZZ = FZZ(rkP);
00060     return Matrix3<Real>(fFXX,fFXY,fFXZ,fFXY,fFYY,fFYZ,fFXZ,fFYZ,fFZZ);
00061 }
00062 //----------------------------------------------------------------------------
00063 template <class Real>
00064 void ImplicitSurface<Real>::GetFrame (const Vector3<Real>& rkP,
00065     Vector3<Real>& rkTangent0, Vector3<Real>& rkTangent1,
00066     Vector3<Real>& rkNormal) const
00067 {
00068     rkNormal = GetGradient(rkP);
00069     Vector3<Real>::GenerateOrthonormalBasis(rkTangent0,rkTangent1,rkNormal);
00070 }
00071 //----------------------------------------------------------------------------
00072 template <class Real>
00073 bool ImplicitSurface<Real>::ComputePrincipalCurvatureInfo (
00074     const Vector3<Real>& rkP, Real& rfCurv0, Real& rfCurv1,
00075     Vector3<Real>& rkDir0, Vector3<Real>& rkDir1)
00076 {
00077     // Principal curvatures and directions for implicitly defined surfaces
00078     // F(x,y,z) = 0.
00079     //
00080     // DF = (Fx,Fy,Fz), L = Length(DF)
00081     //
00082     // D^2 F = +-           -+
00083     //         | Fxx Fxy Fxz |
00084     //         | Fxy Fyy Fyz |
00085     //         | Fxz Fyz Fzz |
00086     //         +-           -+
00087     //
00088     // adj(D^2 F) = +-                                                 -+
00089     //              | Fyy*Fzz-Fyz*Fyz  Fyz*Fxz-Fxy*Fzz  Fxy*Fyz-Fxz*Fyy |
00090     //              | Fyz*Fxz-Fxy*Fzz  Fxx*Fzz-Fxz*Fxz  Fxy*Fxz-Fxx*Fyz |
00091     //              | Fxy*Fyz-Fxz*Fyy  Fxy*Fxz-Fxx*Fyz  Fxx*Fyy-Fxy*Fxy |
00092     //              +-                                                 -+
00093     //
00094     // Gaussian curvature = [DF^t adj(D^2 F) DF]/L^4
00095     // 
00096     // Mean curvature = 0.5*[trace(D^2 F)/L - (DF^t D^2 F DF)/L^3]
00097 
00098     // first derivatives
00099     Real fFX = FX(rkP);
00100     Real fFY = FY(rkP);
00101     Real fFZ = FZ(rkP);
00102     Real fL = Math<Real>::Sqrt(fFX*fFX + fFY*fFY + fFZ*fFZ);
00103     if (fL <= Math<Real>::ZERO_TOLERANCE)
00104     {
00105         return false;
00106     }
00107 
00108     Real fFXFX = fFX*fFX;
00109     Real fFXFY = fFX*fFY;
00110     Real fFXFZ = fFX*fFZ;
00111     Real fFYFY = fFY*fFY;
00112     Real fFYFZ = fFY*fFZ;
00113     Real fFZFZ = fFZ*fFZ;
00114 
00115     Real fInvL = ((Real)1.0)/fL;
00116     Real fInvL2 = fInvL*fInvL;
00117     Real fInvL3 = fInvL*fInvL2;
00118     Real fInvL4 = fInvL2*fInvL2;
00119 
00120     // second derivatives
00121     Real fFXX = FXX(rkP);
00122     Real fFXY = FXY(rkP);
00123     Real fFXZ = FXZ(rkP);
00124     Real fFYY = FYY(rkP);
00125     Real fFYZ = FYZ(rkP);
00126     Real fFZZ = FZZ(rkP);
00127 
00128     // mean curvature
00129     Real fMCurv = ((Real)0.5)*fInvL3*(fFXX*(fFYFY+fFZFZ) + fFYY*(fFXFX+fFZFZ)
00130         + fFZZ*(fFXFX+fFYFY)
00131         - ((Real)2.0)*(fFXY*fFXFY+fFXZ*fFXFZ+fFYZ*fFYFZ));
00132 
00133     // Gaussian curvature
00134     Real fGCurv = fInvL4*(fFXFX*(fFYY*fFZZ-fFYZ*fFYZ)
00135         + fFYFY*(fFXX*fFZZ-fFXZ*fFXZ) + fFZFZ*(fFXX*fFYY-fFXY*fFXY)
00136         + ((Real)2.0)*(fFXFY*(fFXZ*fFYZ-fFXY*fFZZ)
00137         + fFXFZ*(fFXY*fFYZ-fFXZ*fFYY)
00138         + fFYFZ*(fFXY*fFXZ-fFXX*fFYZ)));
00139 
00140     // solve for principal curvatures
00141     Real fDiscr = Math<Real>::Sqrt(Math<Real>::FAbs(fMCurv*fMCurv-fGCurv));
00142     rfCurv0 = fMCurv - fDiscr;
00143     rfCurv1 = fMCurv + fDiscr;
00144 
00145     Real fM00 = ((-(Real)1.0 + fFXFX*fInvL2)*fFXX)*fInvL + (fFXFY*fFXY)*fInvL3
00146         + (fFXFZ*fFXZ)*fInvL3;
00147     Real fM01 = ((-(Real)1.0 + fFXFX*fInvL2)*fFXY)*fInvL + (fFXFY*fFYY)*fInvL3
00148         + (fFXFZ*fFYZ)*fInvL3;
00149     Real fM02 = ((-(Real)1.0 + fFXFX*fInvL2)*fFXZ)*fInvL + (fFXFY*fFYZ)*fInvL3
00150         + (fFXFZ*fFZZ)*fInvL3;
00151     Real fM10 = (fFXFY*fFXX)*fInvL3 + ((-(Real)1.0 + fFYFY*fInvL2)*fFXY)*fInvL
00152         + (fFYFZ*fFXZ)*fInvL3;
00153     Real fM11 = (fFXFY*fFXY)*fInvL3 + ((-(Real)1.0 + fFYFY*fInvL2)*fFYY)*fInvL
00154         + (fFYFZ*fFYZ)*fInvL3;
00155     Real fM12 = (fFXFY*fFXZ)*fInvL3 + ((-(Real)1.0 + fFYFY*fInvL2)*fFYZ)*fInvL
00156         + (fFYFZ*fFZZ)*fInvL3;
00157     Real fM20 = (fFXFZ*fFXX)*fInvL3 + (fFYFZ*fFXY)*fInvL3 + ((-(Real)1.0
00158         + fFZFZ*fInvL2)*fFXZ)*fInvL;
00159     Real fM21 = (fFXFZ*fFXY)*fInvL3 + (fFYFZ*fFYY)*fInvL3 + ((-(Real)1.0
00160         + fFZFZ*fInvL2)*fFYZ)*fInvL;
00161     Real fM22 = (fFXFZ*fFXZ)*fInvL3 + (fFYFZ*fFYZ)*fInvL3 + ((-(Real)1.0
00162         + fFZFZ*fInvL2)*fFZZ)*fInvL;
00163 
00164     // solve for principal directions
00165     Real fTmp1 = fM00 + rfCurv0;
00166     Real fTmp2 = fM11 + rfCurv0;
00167     Real fTmp3 = fM22 + rfCurv0;
00168 
00169     Vector3<Real> akU[3];
00170     Real afLength[3];
00171 
00172     akU[0].X() = fM01*fM12-fM02*fTmp2;
00173     akU[0].Y() = fM02*fM10-fM12*fTmp1;
00174     akU[0].Z() = fTmp1*fTmp2-fM01*fM10;
00175     afLength[0] = akU[0].Length();
00176 
00177     akU[1].X() = fM01*fTmp3-fM02*fM21;
00178     akU[1].Y() = fM02*fM20-fTmp1*fTmp3;
00179     akU[1].Z() = fTmp1*fM21-fM01*fM20;
00180     afLength[1] = akU[1].Length();
00181 
00182     akU[2].X() = fTmp2*fTmp3-fM12*fM21;
00183     akU[2].Y() = fM12*fM20-fM10*fTmp3;
00184     akU[2].Z() = fM10*fM21-fM20*fTmp2;
00185     afLength[2] = akU[2].Length();
00186 
00187     int iMaxIndex = 0;
00188     Real fMax = afLength[0];
00189     if (afLength[1] > fMax)
00190     {
00191         iMaxIndex = 1;
00192         fMax = afLength[1];
00193     }
00194     if (afLength[2] > fMax)
00195     {
00196         iMaxIndex = 2;
00197     }
00198 
00199     Real fInvLength = ((Real)1.0)/afLength[iMaxIndex];
00200     akU[iMaxIndex] *= fInvLength;
00201 
00202     rkDir1 = akU[iMaxIndex];
00203     rkDir0 = rkDir1.UnitCross(Vector3<Real>(fFX,fFY,fFZ));
00204 
00205     return true;
00206 }
00207 //----------------------------------------------------------------------------
00208 
00209 //----------------------------------------------------------------------------
00210 // explicit instantiation
00211 //----------------------------------------------------------------------------
00212 template WM4_FOUNDATION_ITEM
00213 class ImplicitSurface<float>;
00214 
00215 template WM4_FOUNDATION_ITEM
00216 class ImplicitSurface<double>;
00217 //----------------------------------------------------------------------------
00218 }

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