Wm4ImplicitSurface.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 "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     
00078     
00079     
00080     
00081     
00082     
00083     
00084     
00085     
00086     
00087     
00088     
00089     
00090     
00091     
00092     
00093     
00094     
00095     
00096     
00097 
00098     
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     
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     
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     
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     
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     
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 
00211 
00212 template WM4_FOUNDATION_ITEM
00213 class ImplicitSurface<float>;
00214 
00215 template WM4_FOUNDATION_ITEM
00216 class ImplicitSurface<double>;
00217 
00218 }