Wm4ParametricSurface.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 "Wm4ParametricSurface.h"
00019 #include "Wm4Matrix2.h"
00020
00021 namespace Wm4
00022 {
00023
00024 template <class Real>
00025 ParametricSurface<Real>::ParametricSurface (Real fUMin, Real fUMax,
00026 Real fVMin, Real fVMax, bool bRectangular)
00027 {
00028 assert(fUMin < fUMax && fVMin < fVMax);
00029
00030 m_fUMin = fUMin;
00031 m_fUMax = fUMax;
00032 m_fVMin = fVMin;
00033 m_fVMax = fVMax;
00034 m_bRectangular = bRectangular;
00035 }
00036
00037 template <class Real>
00038 ParametricSurface<Real>::~ParametricSurface ()
00039 {
00040 }
00041
00042 template <class Real>
00043 Real ParametricSurface<Real>::GetUMin () const
00044 {
00045 return m_fUMin;
00046 }
00047
00048 template <class Real>
00049 Real ParametricSurface<Real>::GetUMax () const
00050 {
00051 return m_fUMax;
00052 }
00053
00054 template <class Real>
00055 Real ParametricSurface<Real>::GetVMin () const
00056 {
00057 return m_fVMin;
00058 }
00059
00060 template <class Real>
00061 Real ParametricSurface<Real>::GetVMax () const
00062 {
00063 return m_fVMax;
00064 }
00065
00066 template <class Real>
00067 bool ParametricSurface<Real>::IsRectangular () const
00068 {
00069 return m_bRectangular;
00070 }
00071
00072 template <class Real>
00073 void ParametricSurface<Real>::GetFrame (Real fU, Real fV,
00074 Vector3<Real>& rkPosition, Vector3<Real>& rkTangent0,
00075 Vector3<Real>& rkTangent1, Vector3<Real>& rkNormal) const
00076 {
00077 rkPosition = P(fU,fV);
00078
00079 rkTangent0 = PU(fU,fV);
00080 rkTangent1 = PV(fU,fV);
00081 rkTangent0.Normalize();
00082 rkTangent1.Normalize();
00083 rkNormal = rkTangent0.UnitCross(rkTangent1);
00084
00085
00086
00087 rkTangent1 = rkNormal.Cross(rkTangent0);
00088 }
00089
00090 template <class Real>
00091 void ParametricSurface<Real>::ComputePrincipalCurvatureInfo (Real fU, Real fV,
00092 Real& rfCurv0, Real& rfCurv1, Vector3<Real>& rkDir0,
00093 Vector3<Real>& rkDir1)
00094 {
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 Vector3<Real> kDerU = PU(fU,fV);
00119 Vector3<Real> kDerV = PV(fU,fV);
00120 Vector3<Real> kDerUU = PUU(fU,fV);
00121 Vector3<Real> kDerUV = PUV(fU,fV);
00122 Vector3<Real> kDerVV = PVV(fU,fV);
00123
00124
00125 Matrix2<Real> kMetricTensor;
00126 kMetricTensor[0][0] = kDerU.Dot(kDerU);
00127 kMetricTensor[0][1] = kDerU.Dot(kDerV);
00128 kMetricTensor[1][0] = kMetricTensor[0][1];
00129 kMetricTensor[1][1] = kDerV.Dot(kDerV);
00130
00131
00132 Vector3<Real> kNormal = kDerU.UnitCross(kDerV);
00133 Matrix2<Real> kCurvatureTensor;
00134 kCurvatureTensor[0][0] = -kNormal.Dot(kDerUU);
00135 kCurvatureTensor[0][1] = -kNormal.Dot(kDerUV);
00136 kCurvatureTensor[1][0] = kCurvatureTensor[0][1];
00137 kCurvatureTensor[1][1] = -kNormal.Dot(kDerVV);
00138
00139
00140 Real fC0 = kCurvatureTensor.Determinant();
00141 Real fC1 = ((Real)2.0)*kCurvatureTensor[0][1]* kMetricTensor[0][1] -
00142 kCurvatureTensor[0][0]*kMetricTensor[1][1] -
00143 kCurvatureTensor[1][1]*kMetricTensor[0][0];
00144 Real fC2 = kMetricTensor.Determinant();
00145
00146
00147 Real fTemp = Math<Real>::Sqrt(Math<Real>::FAbs(fC1*fC1 -
00148 ((Real)4.0)*fC0*fC2));
00149 Real fMult = ((Real)0.5)/fC2;
00150 rfCurv0 = -fMult*(fC1+fTemp);
00151 rfCurv1 = fMult*(-fC1+fTemp);
00152
00153
00154
00155 Real fA0 = kCurvatureTensor[0][1] - rfCurv0*kMetricTensor[0][1];
00156 Real fA1 = rfCurv0*kMetricTensor[0][0] - kCurvatureTensor[0][0];
00157 Real fLength = Math<Real>::Sqrt(fA0*fA0+fA1*fA1);
00158 if (fLength >= Math<Real>::ZERO_TOLERANCE)
00159 {
00160 rkDir0 = fA0*kDerU + fA1*kDerV;
00161 }
00162 else
00163 {
00164 fA0 = kCurvatureTensor[1][1] - rfCurv0*kMetricTensor[1][1];
00165 fA1 = rfCurv0*kMetricTensor[0][1] - kCurvatureTensor[0][1];
00166 fLength = Math<Real>::Sqrt(fA0*fA0+fA1*fA1);
00167 if (fLength >= Math<Real>::ZERO_TOLERANCE)
00168 {
00169 rkDir0 = fA0*kDerU + fA1*kDerV;
00170 }
00171 else
00172 {
00173
00174 rkDir0 = kDerU;
00175 }
00176 }
00177 rkDir0.Normalize();
00178
00179
00180 rkDir1 = rkDir0.Cross(kNormal);
00181 }
00182
00183
00184
00185
00186
00187 template WM4_FOUNDATION_ITEM
00188 class ParametricSurface<float>;
00189
00190 template WM4_FOUNDATION_ITEM
00191 class ParametricSurface<double>;
00192
00193 }