![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsNURBs.cpp 00003 00004 A (Generic) collection of Splines: 00005 00006 SUKITTI PUNAK (12/16/2005) 00007 UPDATE (12/16/2005) 00008 ******************************************************************************/ 00009 #include "TAPsNURBs.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 //----------------------------------------------------------------------------- 00017 // default constructor 00018 template <typename T> 00019 NURBs<T>::NURBs () 00020 { 00021 m_iUDegree = m_iVDegree = 3; 00022 m_iNumUPts = 6; 00023 m_iNumVPts = 5; 00024 m_iNumKnotU = 8; 00025 m_iNumKnotV = 7; 00026 m_prKnotU = new T[m_iNumKnotU]; 00027 m_prKnotV = new T[m_iNumKnotV]; 00028 /* 00029 m_prKnotU[0] = m_prKnotV[0] = 0; 00030 m_prKnotU[1] = m_prKnotV[1] = 0; 00031 m_prKnotU[2] = m_prKnotV[2] = 0; 00032 m_prKnotU[3] = m_prKnotV[3] = 1; 00033 m_prKnotU[4] = m_prKnotV[4] = 2; 00034 m_prKnotU[5] = m_prKnotV[5] = 2; 00035 m_prKnotU[6] = m_prKnotV[6] = 2; 00036 //*/ 00037 //* 00038 m_prKnotU[0] = m_prKnotV[0] = -2; 00039 m_prKnotU[1] = m_prKnotV[1] = -1; 00040 m_prKnotU[2] = m_prKnotV[2] = 0; 00041 m_prKnotU[3] = m_prKnotV[3] = 1; 00042 m_prKnotU[4] = m_prKnotV[4] = 2; 00043 m_prKnotU[5] = m_prKnotV[5] = 3; 00044 m_prKnotU[6] = m_prKnotV[6] = 4; 00045 m_prKnotU[6] = 5; 00046 //*/ 00047 00048 m_prCtrlPts = new Vector3<T>*[m_iNumVPts]; 00049 for ( int i = 0; i < 5; ++i ) { 00050 m_prCtrlPts[i] = new Vector3<T>[m_iNumUPts]; 00051 } 00052 T x[] = { -1.0, -0.5, -0.2, 0.2, 0.5, 1.0 }; // width in OpenGL 00053 T y[] = { 0.0, 0.5, 1.0, 0.5, 0.0 }; // height in OpenGL 00054 T z[] = { -1.5, -0.75, 0.0, 0.75, 1.5 }; // depth in OpenGL 00055 for ( int i = 0; i < 5; ++i ) { 00056 for ( int j = 0; j < 6; ++j ) { 00057 if ( j == 0 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i]/4, z[i] ); 00058 else if ( j == 1 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i]/2, z[i] ); 00059 else if ( j == 2 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i], z[i] ); 00060 else if ( j == 3 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i], z[i] ); 00061 else if ( j == 4 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i]/2, z[i] ); 00062 else if ( j == 5 ) m_prCtrlPts[i][j].SetXYZ( x[j], y[i]/4, z[i] ); 00063 } 00064 } 00065 //std::cout << "NURBs<" << typeid(T).name() << "> Constructor\n"; 00066 } 00067 template <typename T> 00068 NURBs<T>::NURBs ( Vector3<T> ** ctrlPts, 00069 int numUPts, int numVPts, 00070 int uDegree, int vDegree, 00071 int numOfUKnots, int numOfVKnots, 00072 T * uKnots, T * vKnots ) 00073 { 00074 m_prCtrlPts = ctrlPts; 00075 m_iNumUPts = numUPts; 00076 m_iNumVPts = numVPts; 00077 m_iUDegree = uDegree; 00078 m_iVDegree = vDegree; 00079 m_iNumKnotU = numOfUKnots; 00080 m_iNumKnotV = numOfVKnots; 00081 m_prKnotU = uKnots; 00082 m_prKnotV = vKnots; 00083 //std::cout << "NURBs<" << typeid(T).name() << "> Constructor\n"; 00084 } 00085 //----------------------------------------------------------------------------- 00086 // destructor 00087 template <typename T> 00088 NURBs<T>::~NURBs () 00089 { 00090 if ( m_prCtrlPts != NULL ) { 00091 for ( int i = 0; i < m_iNumVPts; ++i ) { 00092 delete [] m_prCtrlPts[i]; 00093 } 00094 delete [] m_prCtrlPts; 00095 m_prCtrlPts = NULL; 00096 } 00097 if ( m_prKnotU != NULL ) { 00098 delete [] m_prKnotU; 00099 m_prKnotU = NULL; 00100 } 00101 if ( m_prKnotV != NULL ) { 00102 delete [] m_prKnotV; 00103 m_prKnotV = NULL; 00104 } 00105 //std::cout << "NURBs<" << typeid(T).name() << "> Destructor\n"; 00106 } 00107 //----------------------------------------------------------------------------- 00108 // Return A Point On Curve Too 00109 template <typename T> 00110 Vector3<T> NURBs<T>::RetAPointOnSurface ( T u, T v ) 00111 { 00112 int a, b, e, i, j, k; 00113 T ** N = new T*[2]; 00114 T * Nu = new T[m_iNumKnotU]; 00115 T * Nv = new T[m_iNumKnotV]; 00116 if ( m_iNumKnotU >= m_iNumKnotV ) { 00117 N[0] = new T[m_iNumKnotU]; 00118 N[1] = new T[m_iNumKnotU]; 00119 } 00120 else { 00121 N[0] = new T[m_iNumKnotV]; 00122 N[1] = new T[m_iNumKnotV]; 00123 } 00124 Vector3<T> result; 00125 00126 //* 00127 //------------------------------------------------------------------- 00128 // Find basis Nu(u) 00129 //------------------------------------------------------------------- 00130 // Initialize N^0_u 00131 N[0][0] = 0; 00132 for ( k = 0; k < m_iNumKnotU-1; ++k ) { 00133 if ( m_prKnotU[k] <= u && u < m_prKnotU[k+1] ) N[0][k+1] = 1; 00134 else N[0][k+1] = 0; 00135 } 00136 //N[0][k] = 0; 00137 //-------------------------------------------------------------------- 00138 // Start at the next degree, until the u-degree 00139 e = 1; a = 0; b = 1; 00140 while ( e <= m_iUDegree ) { 00141 j = e; 00142 for ( i = 0; i < m_iNumKnotU-1; ++i ) { 00143 if ( i == 0 ) 00144 N[b][i] = ((m_prKnotU[j]-u)/(m_prKnotU[j]-m_prKnotU[i])) * N[a][i+1]; 00145 j = i+e; 00146 N[b][i] = ((u-m_prKnotU[i-1])/(m_prKnotU[j-1]-m_prKnotU[i-1])) * N[a][i] 00147 + ((m_prKnotU[j]-u)/(m_prKnotU[j]-m_prKnotU[i])) * N[a][i+1]; 00148 } 00149 j = i+e; 00150 N[b][i] = ((u-m_prKnotU[i-1])/(m_prKnotU[j-1]-m_prKnotU[i-1])) * N[a][i]; 00151 ++e; 00152 //------------------------------------------------------------ 00153 if ( 0 == a ) { 00154 a = 1; 00155 b = 0; 00156 } 00157 else { 00158 a = 0; 00159 b = 1; 00160 } 00161 } 00162 for ( i = 0; i < m_iNumKnotU; ++i ) Nu[i] = N[a][i]; 00163 //*/ 00164 00165 //* 00166 //------------------------------------------------------------------- 00167 // Find basis Nv(v) 00168 //------------------------------------------------------------------- 00169 // Initialize N^0_v 00170 N[0][0] = 0; 00171 for ( k = 0; k < m_iNumKnotV-1; ++k ) { 00172 if ( m_prKnotV[k] <= v && v < m_prKnotV[k+1] ) N[0][k+1] = 1; 00173 else N[0][k+1] = 0; 00174 } 00175 //N[0][k] = 0; 00176 //-------------------------------------------------------------------- 00177 // Start at the next degree, until the u-degree 00178 e = 1; a = 0; b = 1; 00179 while ( e <= m_iVDegree ) { 00180 j = e; 00181 for ( i = 0; i < m_iNumKnotV-1; ++i ) { 00182 if ( i == 0 ) 00183 N[b][i] = ((m_prKnotV[j]-v)/(m_prKnotV[j]-m_prKnotV[i])) * N[a][i+1]; 00184 j = i+e; 00185 N[b][i] = ((v-m_prKnotV[i-1])/(m_prKnotV[j-1]-m_prKnotV[i-1])) * N[a][i] 00186 + ((m_prKnotV[j]-v)/(m_prKnotV[j]-m_prKnotV[i])) * N[a][i+1]; 00187 } 00188 j = i+e; 00189 N[b][i] = ((v-m_prKnotV[i-1])/(m_prKnotV[j-1]-m_prKnotV[i-1])) * N[a][i]; 00190 ++e; 00191 //------------------------------------------------------------ 00192 if ( 0 == a ) { 00193 a = 1; 00194 b = 0; 00195 } 00196 else { 00197 a = 0; 00198 b = 1; 00199 } 00200 } 00201 for ( i = 0; i < m_iNumKnotV; ++i ) Nv[i] = N[a][i]; 00202 //*/ 00203 00204 result.SetXYZ( 0,0,0 ); 00205 for ( i = 0; i < m_iNumVPts; ++i ) { 00206 for ( j = 0; j < m_iNumUPts; ++j ) { 00207 result += m_prCtrlPts[i][j]*Nu[j]*Nv[i]; 00208 } 00209 //result *= Nv[i]; 00210 } 00211 delete [] N[0]; 00212 delete [] N[1]; 00213 delete [] N; 00214 delete [] Nu; 00215 delete [] Nv; 00216 00217 return result; 00218 } 00219 //* 00220 //----------------------------------------------------------------------------- 00221 // Return A Point On Curve Too 00222 template <typename T> 00223 Vector3<T> NURBs<T>::RetAPointOnCurveToo ( T u ) 00224 { 00225 int i, j, k; 00226 T ** N = new T*[2]; 00227 if ( m_iNumKnotU >= m_iNumKnotV ) { 00228 N[0] = new T[m_iNumKnotU]; 00229 N[1] = new T[m_iNumKnotU]; 00230 } 00231 else { 00232 N[0] = new T[m_iNumKnotV]; 00233 N[1] = new T[m_iNumKnotV]; 00234 } 00235 Vector3<T> result; 00236 00237 //* 00238 //------------------------------------------------------------------- 00239 // Find basis Nu(u) 00240 //------------------------------------------------------------------- 00241 // Initialize N^0_u 00242 N[0][0] = 0; 00243 for ( k = 0; k < m_iNumKnotU-1; ++k ) { 00244 if ( m_prKnotU[k] <= u && u < m_prKnotU[k+1] ) N[0][k+1] = 1; 00245 else N[0][k+1] = 0; 00246 } 00247 //-------------------------------------------------------------------- 00248 // Start at the next degree, until the u-degree 00249 int e = 1; 00250 int a = 0, b = 1; 00251 while ( e <= m_iUDegree ) { 00252 j = e; 00253 for ( i = 0; i < m_iNumKnotU-1; ++i ) { 00254 if ( i == 0 ) 00255 N[b][i] = ((m_prKnotU[j]-u)/(m_prKnotU[j]-m_prKnotU[i])) * N[a][i+1]; 00256 j = i+e; 00257 N[b][i] = ((u-m_prKnotU[i-1])/(m_prKnotU[j-1]-m_prKnotU[i-1])) * N[a][i] 00258 + ((m_prKnotU[j]-u)/(m_prKnotU[j]-m_prKnotU[i])) * N[a][i+1]; 00259 } 00260 j = i+e; 00261 N[b][i] = ((u-m_prKnotU[i-1])/(m_prKnotU[j-1]-m_prKnotU[i-1])) * N[a][i]; 00262 ++e; 00263 //------------------------------------------------------------ 00264 if ( 0 == a ) { 00265 a = 1; 00266 b = 0; 00267 } 00268 else { 00269 a = 0; 00270 b = 1; 00271 } 00272 } 00273 //*/ 00274 00275 result.SetXYZ( 0,0,0 ); 00276 i = 0; 00277 for ( j = 0; j < m_iNumUPts; ++j ) { 00278 result += m_prCtrlPts[i][j]*N[a][j]; 00279 } 00280 delete [] N[0]; 00281 delete [] N[1]; 00282 delete [] N; 00283 00284 return result; 00285 } 00286 //* 00287 //----------------------------------------------------------------------------- 00288 // Return A Point On Curve 00289 template <typename T> 00290 Vector3<T> NURBs<T>::RetAPointOnCurve ( T u ) 00291 { 00292 int i, j, k, d = m_iUDegree; 00293 Vector3<T> ** c = new Vector3<T>*[2]; 00294 c[0] = new Vector3<T>[d+1]; 00295 c[1] = new Vector3<T>[d]; 00296 //------------------------------------------------------------------- 00297 // Find the interval of knots 00298 for ( k = 0; k < m_iNumKnotU-1; ++k ) { 00299 if ( u < m_prKnotU[k] ) return Vector3<T>( 0, 0, 0 ); 00300 else if ( u < m_prKnotU[k+1] ) break; 00301 } 00302 if ( k == m_iNumKnotU-1 ) return Vector3<T>( 0, 0, 0 ); 00303 //------------------------------------------------------------------- 00304 // Remember ctrl pts 00305 for ( i=0, j=k-d+1; i<=d; ++i ) { 00306 //c[0][i] = m_prCtrlPts[j+i][2]; 00307 c[0][i] = m_prCtrlPts[1][j+i]; 00308 } 00309 int e = 1; // start at the next level, until the degree 00310 T w; 00311 int a = 0, b = 1; 00312 while ( e <= d ) { 00313 for ( i = 0; i <= d-e; ++i ) { 00314 j = k+i+1; 00315 w = ( u - m_prKnotU[j] ) / ( m_prKnotU[k-d+e+i] - m_prKnotU[j] ); 00316 //c[b][i] = (1.0-w)*c[a][i] + w*c[a][i+1]; 00317 c[b][i] = (1.0-w)*c[a][i+1] + w*c[a][i]; 00318 } 00319 if ( 0 == a ) { 00320 a = 1; 00321 b = 0; 00322 } 00323 else { 00324 a = 0; 00325 b = 1; 00326 } 00327 ++e; 00328 } 00329 00330 Vector3<T> result = c[a][0]; 00331 delete [] c[0]; 00332 delete [] c[1]; 00333 delete [] c; 00334 00335 return result; 00336 } 00337 //*/ 00338 #if defined(__gl_h_) || defined(__GL_H__) 00339 //============================================================================= 00340 // OpenGL Fns 00341 //----------------------------------------------------------------------------- 00342 // destructor 00343 template <typename T> 00344 void NURBs<T>::DrawByOpenGL () 00345 { 00346 glPushMatrix(); 00347 // Draw ctrl pts 00348 // if ( gShowNurbsPts ) { 00349 glColor3f( 1, 0, 0 ); 00350 glPointSize( 7.0 ); 00351 glDisable( GL_LIGHTING ); 00352 glBegin( GL_POINTS ); 00353 for ( int i = 0; i < m_iNumVPts; ++i ) { 00354 for ( int j = 0; j < m_iNumUPts; ++j ) { 00355 //glVertex3fv( m_prCtrlPts[i][j] ); 00356 glVertex3f( m_prCtrlPts[i][j][0], m_prCtrlPts[i][j][1], m_prCtrlPts[i][j][2] ); 00357 } 00358 } 00359 glEnd(); 00360 glEnable( GL_LIGHTING ); 00361 // } 00362 glPopMatrix(); 00363 } 00364 #endif 00365 //============================================================================= 00366 00367 //****************************************************************************** 00368 //============================================================================= 00369 END_NAMESPACE_TAPs 00370 //----------------------------------------------------------------------------- 00371 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00372 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8