TAPs 0.7.7.3
TAPsNURBs.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines