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 }