Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gunu_raise_degree.cpp

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */ 
00019 
00020 
00021  
00022 #include "stdafx.h"
00023 
00024 #include <iostream>
00025 
00026 #include "gul_types.h"
00027 #include "gul_vector.h"
00028 #include "gunu_raise_degree.h"
00029 
00030 namespace gunu {
00031 
00032 using gul::rtr;
00033 using gul::Max;
00034 using gul::Min;
00035 using gul::Ptr;
00036 using gul::point;
00037 using gul::hpoint;
00038 using gul::point2;
00039 using gul::hpoint2;
00040 using gul::point1;
00041 using gul::hpoint1;
00042 using gul::set;
00043 
00044 /*-------------------------------------------------------------------------*//**
00045   raise the degree 'p' of a curve to 'p+t'. this function doesn't reserves
00046   memory for Uh and Q, in the worst case for Q: p + (n-p+1)*(t+1), and for
00047   Uh: 2*p + (n-p+2)*(t+1) elements are needed, the function returns the new 
00048   number of controlpoints - 1                                                 */
00049 /*----------------------------------------------------------------------------*/
00050 template< class T, class HP >
00051 int ElevateCurveDegree( int n, int p, const Ptr<T>& U, const Ptr<HP>& Pw, int t,
00052                         Ptr<T>& Uh, Ptr<HP>& Qw )
00053 {
00054   int m,i,mpi,j,ph,ph2,mh,kind,r,a,b,cind;
00055   int mul,oldr,lbz,rbz,k,save,s,first,last,kj,tr;
00056   T inv,ua,ub,numer,den,bet,alf,gam;
00057   Ptr< Ptr<T> > bezalfs;
00058   Ptr<T> alfs;
00059   Ptr<HP> bpts,ebpts,Nextbpts;
00060 
00061   bezalfs.reserve_pool(p+t+1);
00062   for( i = 0; i <= p+t; i++ )
00063     bezalfs[i].reserve_pool(p+1);
00064 
00065   bpts.reserve_pool(p+1);
00066   ebpts.reserve_pool(p+t+1);
00067 
00068   if( p > 1 )
00069   {
00070     Nextbpts.reserve_pool(p-1);
00071     alfs.reserve_pool(p-1); 
00072   }
00073   m = n + p + 1;
00074   ph = p + t;
00075   ph2 = ph / 2;
00076 
00077 /* --- calc coefficients for raising the degree of the bezier segments ---- */  
00078 
00079   bezalfs[0][0] = (T)1;
00080   bezalfs[ph][p] = (T)1;
00081   
00082   for( i = 1; i <= ph2; i++ )
00083   {
00084     inv = (T)1 / rtr<T>::BinCoeff(ph,i);
00085     mpi = Min( p, i );
00086     
00087     for( j = Max( 0,i-t ); j <= mpi; j++ )
00088       bezalfs[i][j] = inv * rtr<T>::BinCoeff(p,j) * rtr<T>::BinCoeff(t,i-j);
00089   }    
00090   for( i = ph2+1; i <= ph-1; i++ )
00091   {
00092     mpi = Min( p, i );
00093     for( j = Max( 0,i-t ); j <= mpi; j++ )
00094       bezalfs[i][j] = bezalfs[ph-i][p-j];
00095   }       
00096   mh = ph;
00097   kind = ph+1;
00098   r = -1;
00099   a = p;
00100   b = p+1;
00101   cind = 1;
00102   ua = U[0];
00103   Qw[0] = Pw[0];
00104   
00105   for( i = 0; i <= ph; i++ )
00106     Uh[i] = ua;
00107     
00108   for( i = 0; i <= p; i++ )
00109     bpts[i] = Pw[i];  
00110     
00111   while( b < m )
00112   {
00113     i = b;
00114     while( (b < m) && (U[b] == U[b+1]) )
00115       b++;
00116 
00117     mul = b-i+1;
00118     mh = mh + mul + t;
00119     ub = U[b];
00120     oldr = r;
00121     r = p - mul;
00122     
00123     if( oldr > 0)
00124       lbz = (oldr+2) / 2;
00125     else
00126       lbz = 1;
00127 
00128     if( r > 0 )
00129       rbz = ph - ((r+1) / 2);
00130     else
00131       rbz = ph;  
00132 
00133     if( r > 0 )
00134     {
00135       numer = ub - ua;
00136       for( k = p; k > mul; k-- )
00137         alfs[k-mul-1] = numer / (U[a+k]-ua);
00138       for( j = 1; j <= r; j++ )  
00139       {
00140         save = r - j;
00141         s = mul + j;            
00142 
00143         for( k = p; k >= s; k-- )
00144           bpts[k] = ((T)1 - alfs[k-s]) * bpts[k-1] + alfs[k-s] * bpts[k];
00145 
00146         Nextbpts[save] = bpts[p];
00147       }  
00148     }
00149     for( i = lbz; i <= ph; i++ )
00150     {
00151       set( ebpts[i], (T)0 );
00152       mpi = Min( p, i );
00153 
00154       for( j = Max(0,i-t); j <= mpi; j++ )
00155         ebpts[i] = ebpts[i] + bezalfs[i][j] * bpts[j];
00156     }
00157 
00158     if( oldr > 1 )
00159     {
00160       first = kind-2;
00161       last = kind;
00162       den = ub-ua;
00163       bet = (ub-Uh[kind-1])/den;
00164       
00165       for( tr = 1; tr < oldr; tr++ )
00166       {        
00167         i = first;
00168         j = last;
00169         kj = j-kind+1;
00170         while( j - i > tr )
00171         {
00172           if( i < cind )
00173           {
00174             alf = (ub-Uh[i])/(ua-Uh[i]);
00175             Qw[i] = ((T)1 - alf) * Qw[i-1] + alf * Qw[i];
00176           }        
00177           if( j >= lbz )
00178           {
00179             if( j - tr <= kind-ph+oldr )
00180             {  
00181               gam = (ub-Uh[j-tr])/den;
00182               ebpts[kj] = ((T)1 - gam) * ebpts[kj+1] + gam * ebpts[kj];
00183             }
00184             else
00185               ebpts[kj] = ((T)1 - bet) * ebpts[kj+1] + bet * ebpts[kj];
00186           }
00187           i++;
00188           j--;
00189           kj--;
00190         }      
00191         
00192         first--;
00193         last++;
00194       }                    
00195     }    
00196     if( a != p )
00197       for( i = 0; i < ph-oldr; i++ )
00198       {
00199         Uh[kind] = ua;
00200         kind++;
00201       }      
00202     for( j = lbz; j <= rbz; j++ )
00203     {
00204       Qw[cind] = ebpts[j];
00205       cind++;
00206     }
00207     if( b < m )
00208     {
00209       for( j = 0; j < r; j++ )
00210         bpts[j] = Nextbpts[j];
00211       for( j = r; j <= p; j++ )
00212         bpts[j] = Pw[b-p+j];
00213       a = b;
00214       b++;
00215       ua = ub;
00216     }
00217     else
00218       for( i = 0; i <= ph; i++ )
00219         Uh[kind+i] = ub;
00220   }                      
00221   return( mh - ph - 1 );
00222 }          
00223 template int ElevateCurveDegree( 
00224    int n, int p, const Ptr<float>& U, const Ptr< point<float> >& Pw, int t,
00225    Ptr<float>& Uh, Ptr< point<float> >& Qw );
00226 template int ElevateCurveDegree( 
00227    int n, int p, const Ptr<float>& U, const Ptr< hpoint<float> >& Pw, int t,
00228    Ptr<float>& Uh, Ptr< hpoint<float> >& Qw );
00229 template int ElevateCurveDegree( 
00230    int n, int p, const Ptr<float>& U, const Ptr< point2<float> >& Pw, int t,
00231    Ptr<float>& Uh, Ptr< point2<float> >& Qw );
00232 template int ElevateCurveDegree( 
00233    int n, int p, const Ptr<float>& U, const Ptr< hpoint2<float> >& Pw, int t,
00234    Ptr<float>& Uh, Ptr< hpoint2<float> >& Qw );
00235 
00236 template int ElevateCurveDegree( 
00237    int n, int p, const Ptr<double>& U, const Ptr< point<double> >& Pw, int t,
00238    Ptr<double>& Uh, Ptr< point<double> >& Qw );
00239 template int ElevateCurveDegree( 
00240    int n, int p, const Ptr<double>& U, const Ptr< hpoint<double> >& Pw, int t,
00241    Ptr<double>& Uh, Ptr< hpoint<double> >& Qw );
00242 template int ElevateCurveDegree( 
00243    int n, int p, const Ptr<double>& U, const Ptr< point2<double> >& Pw, int t,
00244    Ptr<double>& Uh, Ptr< point2<double> >& Qw );
00245 template int ElevateCurveDegree( 
00246    int n, int p, const Ptr<double>& U, const Ptr< hpoint2<double> >& Pw, int t,
00247    Ptr<double>& Uh, Ptr< hpoint2<double> >& Qw );
00248 
00249 /*-------------------------------------------------------------------------*//**
00250   raise the degree 'pu' or 'pv' of a surface by 't'. this function doesn't
00251   reserves memory for Uh,Vh and Qw, they must be dimensioned in u or v 
00252   direction like for curves.                                                  */
00253 /*----------------------------------------------------------------------------*/
00254 template< class T, class HP >
00255 void ElevateSurfaceDegreeU( 
00256               int nu, int pu, const Ptr<T>& U, int nv, int pv, const Ptr<T>& V,
00257               const Ptr< Ptr<HP> >& Pw, int t,
00258               int *nhu, Ptr<T>& Uh, int *nhv, Ptr<T>& Vh,
00259               Ptr< Ptr<HP> >& Qw )
00260 {
00261   int m,i,mpi,j,ph,ph2,mh,kind,r,a,b,cind,row;
00262   int mul,oldr,lbz,rbz,k,save,s,first,last,kj,tr;
00263   T inv,ua,ub,numer,den,bet,alf,gam;
00264   Ptr< Ptr<T> > bezalfs;
00265   Ptr<T> alfs;
00266   Ptr< Ptr< HP > > bpts,ebpts,Nextbpts;
00267 
00268   bezalfs.reserve_pool(pu+t+1);
00269   for( i = 0; i <= pu+t; i++ )
00270     bezalfs[i].reserve_pool(pu+1);
00271 
00272   bpts.reserve_pool(nv+1);
00273   for( i = 0; i <= nv; i++ )
00274     bpts[i].reserve_pool(pu+1);
00275 
00276   ebpts.reserve_pool(nv+1);
00277   for( i = 0; i <= nv; i++ )
00278     ebpts[i].reserve_pool(pu+t+1);
00279 
00280   if( pu > 1 )
00281   {
00282     Nextbpts.reserve_pool(nv+1);
00283     for( i = 0; i <= nv; i++ )
00284       Nextbpts[i].reserve_pool(pu-1);
00285 
00286     alfs.reserve_pool(pu-1);
00287   }
00288   m = nu + pu + 1;
00289   ph = pu + t;
00290   ph2 = ph / 2;
00291   
00292 /* --- calc coefficients for raising the degree of the bezier segments ---- */  
00293 
00294   bezalfs[0][0] = 1.0;
00295   bezalfs[ph][pu] = 1.0;
00296   
00297   for( i = 1; i <= ph2; i++ )
00298   {
00299     inv = (T)1 / rtr<T>::BinCoeff( ph, i );
00300     mpi = Min( pu, i );
00301     
00302     for( j = Max( 0,i-t ); j <= mpi; j++ )
00303       bezalfs[i][j] = inv * rtr<T>::BinCoeff(pu,j) * rtr<T>::BinCoeff(t,i-j);
00304   }    
00305   for( i = ph2+1; i <= ph-1; i++ )
00306   {
00307     mpi = Min( pu, i );
00308     for( j = Max( 0,i-t ); j <= mpi; j++ )
00309     bezalfs[i][j] = bezalfs[ph-i][pu-j];
00310   }       
00311   mh = ph;
00312   kind = ph+1;
00313   r = -1;
00314   a = pu;
00315   b = pu+1;
00316   cind = 1;
00317   ua = U[0];
00318   for( row = 0; row <= nv; row++ )
00319     Qw[row][0] = Pw[row][0];
00320   
00321   for( i = 0; i <= ph; i++ )
00322     Uh[i] = ua;
00323     
00324   for( row = 0; row <= nv; row++ )
00325     for( i = 0; i <= pu; i++ )
00326       bpts[row][i] = Pw[row][i];  
00327     
00328   while( b < m )
00329   {
00330     i = b;
00331     while( (b < m) && (U[b] == U[b+1]) )
00332       b++;
00333 
00334     mul = b-i+1;
00335     mh = mh + mul + t;
00336     ub = U[b];
00337     oldr = r;
00338     r = pu - mul;
00339     
00340     if( oldr > 0)
00341       lbz = (oldr+2) / 2;
00342     else
00343       lbz = 1;
00344 
00345     if( r > 0 )
00346       rbz = ph - ((r+1) / 2);
00347     else
00348       rbz = ph;  
00349 
00350     if( r > 0 )
00351     {
00352       numer = ub - ua;
00353       for( k = pu; k > mul; k-- )
00354         alfs[k-mul-1] = numer / (U[a+k]-ua);
00355       for( j = 1; j <= r; j++ )  
00356       {
00357         save = r - j;
00358         s = mul + j;            
00359 
00360         for( row = 0; row <= nv; row++ )
00361         {
00362           for( k = pu; k >= s; k-- )
00363           {
00364             bpts[row][k] = 
00365                ((T)1 - alfs[k-s]) * bpts[row][k-1] + alfs[k-s] * bpts[row][k];
00366           }  
00367           Nextbpts[row][save] = bpts[row][pu];
00368         }
00369       }  
00370     }
00371     for( row = 0; row <= nv; row++ )
00372     {
00373       for( i = lbz; i <= ph; i++ )
00374       {
00375         set( ebpts[row][i], (T)0 );
00376         mpi = Min( pu, i );
00377         for( j = Max(0,i-t); j <= mpi; j++ )
00378           ebpts[row][i] = ebpts[row][i] + bezalfs[i][j] * bpts[row][j];      
00379       }
00380     }
00381     if( oldr > 1 )
00382     {
00383       first = kind-2;
00384       last = kind;
00385       den = ub-ua;
00386       bet = (ub-Uh[kind-1])/den;
00387       
00388       for( tr = 1; tr < oldr; tr++ )
00389       {        
00390         i = first;
00391         j = last;
00392         kj = j-kind+1;
00393         while( j - i > tr )
00394         {
00395           if( i < cind )
00396           {
00397             alf = (ub-Uh[i])/(ua-Uh[i]);
00398             for( row = 0; row <= nv; row++ )
00399               Qw[row][i] = ((T)1 - alf) * Qw[row][i-1] + alf * Qw[row][i];
00400           }        
00401           if( j >= lbz )
00402           {
00403             if( j - tr <= kind-ph+oldr )
00404             {  
00405               gam = (ub-Uh[j-tr])/den;
00406               for( row = 0; row <= nv; row++ )
00407               {
00408                 ebpts[row][kj] = 
00409                      ((T)1 - gam) * ebpts[row][kj+1] + gam * ebpts[row][kj];
00410               }
00411             }
00412             else
00413             {
00414               for( row = 0; row <= nv; row++ )
00415               {
00416                 ebpts[row][kj] = 
00417                      ((T)1 - bet) * ebpts[row][kj+1] + bet * ebpts[row][kj];
00418               }
00419             }
00420           }
00421           i++;
00422           j--;
00423           kj--;
00424         }      
00425         
00426         first--;
00427         last++;
00428       }                    
00429     }    
00430     if( a != pu )
00431       for( i = 0; i < ph-oldr; i++ )
00432       {
00433         Uh[kind] = ua;
00434         kind++;
00435       }
00436     for( j = lbz; j <= rbz; j++ )
00437     {
00438       for( row = 0; row <= nv; row++ )
00439         Qw[row][cind] = ebpts[row][j];
00440       cind++;
00441     }
00442     if( b < m )
00443     {
00444       for( row = 0; row <= nv; row++ )
00445       {
00446         for( j = 0; j < r; j++ )
00447           bpts[row][j] = Nextbpts[row][j];
00448         for( j = r; j <= pu; j++ )
00449           bpts[row][j] = Pw[row][b-pu+j];
00450       }
00451       a = b;
00452       b++;
00453       ua = ub;
00454     }
00455     else
00456       for( i = 0; i <= ph; i++ )
00457         Uh[kind+i] = ub;
00458   }                      
00459   *nhu = mh - ph - 1;
00460 
00461   // knot vector in V direction only needs to be copied
00462   for( i = 0; i < nv + pv + 2; i++ )
00463     Vh[i] = V[i];
00464 
00465   *nhv = nv;  
00466 }          
00467 // template instantiation
00468 template void ElevateSurfaceDegreeU( 
00469       int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,
00470       const Ptr< Ptr< point<float> > >& Pw, int t,
00471       int *nhu, Ptr<float>& Uh, int *nhv, Ptr<float>& Vh,
00472       Ptr< Ptr< point<float> > >& Qw );
00473 template void ElevateSurfaceDegreeU( 
00474       int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,
00475       const Ptr< Ptr< hpoint<float> > >& Pw, int t,
00476       int *nhu, Ptr<float>& Uh, int *nhv, Ptr<float>& Vh,
00477       Ptr< Ptr< hpoint<float> > >& Qw );
00478 template void ElevateSurfaceDegreeU( 
00479       int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,
00480       const Ptr< Ptr< point1<float> > >& Pw, int t,
00481       int *nhu, Ptr<float>& Uh, int *nhv, Ptr<float>& Vh,
00482       Ptr< Ptr< point1<float> > >& Qw );
00483 template void ElevateSurfaceDegreeU( 
00484       int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,
00485       const Ptr< Ptr< hpoint1<float> > >& Pw, int t,
00486       int *nhu, Ptr<float>& Uh, int *nhv, Ptr<float>& Vh,
00487       Ptr< Ptr< hpoint1<float> > >& Qw );
00488 
00489 template void ElevateSurfaceDegreeU( 
00490     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,
00491     const Ptr< Ptr< point<double> > >& Pw, int t,
00492     int *nhu, Ptr<double>& Uh, int *nhv, Ptr<double>& Vh,
00493     Ptr< Ptr< point<double> > >& Qw );
00494 template void ElevateSurfaceDegreeU( 
00495     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,
00496     const Ptr< Ptr< hpoint<double> > >& Pw, int t,
00497     int *nhu, Ptr<double>& Uh, int *nhv, Ptr<double>& Vh,
00498     Ptr< Ptr< hpoint<double> > >& Qw );
00499 template void ElevateSurfaceDegreeU( 
00500     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,
00501     const Ptr< Ptr< point1<double> > >& Pw, int t,
00502     int *nhu, Ptr<double>& Uh, int *nhv, Ptr<double>& Vh,
00503     Ptr< Ptr< point1<double> > >& Qw );
00504 template void ElevateSurfaceDegreeU( 
00505     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,
00506     const Ptr< Ptr< hpoint1<double> > >& Pw, int t,
00507     int *nhu, Ptr<double>& Uh, int *nhv, Ptr<double>& Vh,
00508     Ptr< Ptr< hpoint1<double> > >& Qw );
00509 
00510 
00511 }
00512 
00513 
00514         

Generated on Mon Jan 21 04:17:41 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001