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

gunu_bezier_derivatives.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 #include "stdafx.h"
00021 
00022 #include <iostream>
00023 
00024 #include "gul_types.h"
00025 #include "gul_vector.h"
00026 #include "guar_bincoeff.h"
00027 #include "gunu_basics.h"
00028 #include "gunu_derivatives.h"
00029 
00030 
00031 namespace gunu {
00032 
00033 using gul::rtr;
00034 using gul::point;
00035 using gul::point1;
00036 using gul::point2;
00037 using gul::hpoint;
00038 using gul::hpoint1;
00039 using gul::hpoint2;
00040 using gul::set;
00041 using gul::euclid;
00042 using gul::ortho;
00043 using gul::Max;
00044 
00045 /************************************************************************
00046   The following functions are just simplifications for Bezier functions.
00047   The only difference to the corresponding Nurbs functions is, that
00048   the knot span searching is missing, since Bezier knot vectors have
00049   only one knot span
00050 *************************************************************************/
00051 
00052 /*-------------------------------------------------------------------------
00053   Calculates the first 'd' derivatives of a curve at a point 'u'. The results
00054   are homogeneous points (like the control points), returned in 'CK[]'
00055   (see "The NURBS Book")
00056 --------------------------------------------------------------------------- */  
00057 template< class T, class EP >
00058 void BezierBSPCurveDerivatives( 
00059            const T u, const int p, const Ptr< T >& U,
00060            const Ptr< EP >& Pw, const int d, Ptr< EP >& CK )
00061 {
00062   int du,k,j,span;
00063   EP v1;
00064   Ptr< Ptr< T > > ders;
00065     
00066   du = Min( d, p );
00067 
00068   ders.reserve_place( reserve_stack(Ptr< T >,du+1), du+1 );
00069   for( j = 0; j < p+1; j++ )
00070     ders[j].reserve_place( reserve_stack(T,p+1), p+1 );
00071 
00072   for( k = p+1; k <= d; k++ )
00073     set( CK[k], (T)0.0 );   /* Ableitungen > Grad = 0 */
00074 
00075   span = p;
00076   CalcDersBasisFuns( u, span, p, du, U, ders );
00077   
00078   for( k = 0; k <= du; k++ )
00079   {
00080     set( CK[k], (T)0.0 );
00081     for( j = 0; j <= p; j++ )
00082     {
00083       v1 = ders[k][j] * Pw[span-p+j];
00084       CK[k] = CK[k] + v1;
00085     }
00086   }
00087 }  
00088 // template instantiation
00089 template void BezierBSPCurveDerivatives( 
00090      const float u, const int p, const Ptr< float >& U,
00091      const Ptr< point<float> >& Pw, const int d, Ptr< point<float> >& CK );
00092 template
00093 void BezierBSPCurveDerivatives( 
00094       const double u, const int p, const Ptr< double >& U,
00095       const Ptr< point<double> >& Pw, const int d, Ptr< point<double> >& CK );
00096 template
00097 void BezierBSPCurveDerivatives( 
00098        const float u, const int p, const Ptr< float >& U,
00099        const Ptr< point2<float> >& Pw, const int d, Ptr< point2<float> >& CK );
00100 template
00101 void BezierBSPCurveDerivatives( 
00102       const double u, const int p, const Ptr< double >& U,
00103       const Ptr< point2<double> >& Pw, const int d, Ptr< point2<double> >& CK );
00104 
00105 /*---------------------------------------------------------------------------
00106   Calculates mixed partial derivatives of a NURBS surface. Let 'k' and 'l' be
00107   the number of derivatives in 'u' and 'v' direction, then all mixed ders with
00108   'k+l <= d' are calculated. They are returned in 'SKL[k][l]'.  
00109   (see "The NURBS Book")
00110 ------------------------------------------------------------------------- */  
00111 template< class T, class EP >
00112 void BezierBSPSurfaceDerivatives(
00113                 const T u, const T v,
00114                 const int pu, const Ptr< T >& U,
00115                 const int pv, const Ptr< T >& V,
00116                 const Ptr< Ptr< EP > >& Pw,
00117                 const int d, Ptr< Ptr< EP > >& SKL )
00118 {                
00119   int du,dv,k,l,uspan,vspan,s,r,dd;
00120   EP v1;
00121   Ptr< EP > temp;
00122   Ptr< Ptr< T > > Nu,Nv;
00123 
00124   du = Min( d, pu );
00125   dv = Min( d, pv );
00126 
00127   Nu.reserve_place( reserve_stack(Ptr< T >,du+1), du+1 );
00128   for( k = 0; k < pu+1; k++ )
00129     Nu[k].reserve_place( reserve_stack(T,pu+1), pu+1 );
00130 
00131   Nv.reserve_place( reserve_stack(Ptr< T >,dv+1), dv+1 );
00132   for( k = 0; k < pv+1; k++ )
00133     Nv[k].reserve_place( reserve_stack(T,pv+1), pv+1 );
00134 
00135   temp.reserve_place( reserve_stack(EP,pv+1), pv+1 );
00136 
00137   for( k = pu+1; k <= d; k++ )
00138     for( l = 0; l <= d - k; l++ )
00139       set( SKL[k][l], (T)0.0 );
00140       
00141   for( l = pv+1; l <= d; l++ )
00142     for( k = 0; k <= d - l; k++ )
00143       set( SKL[k][l], (T)0.0 );
00144       
00145   uspan = pu;
00146   CalcDersBasisFuns( u, uspan, pu, du, U, Nu );
00147  
00148   vspan = pv;
00149   CalcDersBasisFuns( v, vspan, pv, dv, V, Nv );
00150   
00151   for( k = 0; k <= du; k++ )
00152   {
00153     for( s = 0; s <= pv; s++ )
00154     {
00155       set( temp[s], (T)0.0 );
00156       for( r = 0; r <= pu; r++ )
00157       {
00158         v1 = Nu[k][r] * Pw[vspan-pv+s][uspan-pu+r];
00159         temp[s] = temp[s] + v1;
00160       }  
00161     }
00162     dd = Min( d - k, dv );
00163     for( l = 0; l <= dd; l++ )
00164     {
00165       set( SKL[k][l], (T)0.0 );
00166       for( s = 0; s <= pv; s++ )
00167       {
00168         v1 = Nv[l][s] * temp[s];
00169         SKL[k][l] = SKL[k][l] + v1;
00170       }
00171     }
00172   }
00173 }  
00174 // template instantiation
00175 template void BezierBSPSurfaceDerivatives(
00176                 const float u, const float v,
00177                 const int pu, const Ptr< float >& U,
00178                 const int pv, const Ptr< float >& V,
00179                 const Ptr< Ptr< point<float> > >& Pw,
00180                 const int d, Ptr< Ptr< point<float> > >& SKL );           
00181 template void BezierBSPSurfaceDerivatives(
00182                 const double u, const double v,
00183                 const int pu, const Ptr< double >& U,
00184                 const int pv, const Ptr< double >& V,
00185                 const Ptr< Ptr< point<double> > >& Pw,
00186                 const int d, Ptr< Ptr< point<double> > >& SKL );
00187 
00188 template void BezierBSPSurfaceDerivatives(
00189                 const float u, const float v,
00190                 const int pu, const Ptr< float >& U,
00191                 const int pv, const Ptr< float >& V,
00192                 const Ptr< Ptr< hpoint<float> > >& Pw,
00193                 const int d, Ptr< Ptr< hpoint<float> > >& SKL );           
00194 template void BezierBSPSurfaceDerivatives(
00195                 const double u, const double v,
00196                 const int pu, const Ptr< double >& U,
00197                 const int pv, const Ptr< double >& V,
00198                 const Ptr< Ptr< hpoint<double> > >& Pw,
00199                 const int d, Ptr< Ptr< hpoint<double> > >& SKL );
00200 
00201 /*-------------------------------------------------------------------------
00202   Calculates the first 'd' partial derivatives of the projection of a NURBS
00203   curve into euclidian space (3-dimensions), so the calculated ders are points
00204   in 3-dimensional space   
00205   (see "The NURBS Book")
00206 ------------------------------------------------------------------------- */  
00207 template< class T, class HP, class EP >
00208 void BezierCurveDerivatives(
00209                     const T u, const int p,
00210                     const Ptr< T >& U, const Ptr< HP >& Pw, const int d,
00211                     Ptr< EP >& CK )             
00212 {
00213   Ptr< HP > CKh;
00214   EP v,v1;
00215   T w0;
00216   int k,i;
00217 
00218   CKh.reserve_place( reserve_stack(HP,d+1), d+1 );
00219      
00220   BezierBSPCurveDerivatives<T,HP>( u, p, U, Pw, d, CKh );
00221 
00222   w0 = CKh[0].w;
00223   
00224   for( k = 0; k <= d; k++ )
00225   {
00226     v = ortho( CKh[k] );
00227     
00228     for( i = 1; i <= k; i++ )
00229     {
00230       v1 = (rtr<T>::BinCoeff(k,i) * CKh[i].w) * CK[k-i];
00231       v = v - v1;
00232     }
00233     CK[k] = ((T)1.0 / w0) * v;       
00234   }
00235 }
00236 // template instantiation
00237 template void BezierCurveDerivatives(
00238           const float u, const int p,
00239           const Ptr< float >& U, const Ptr< hpoint<float> >& Pw, const int d,
00240           Ptr< point<float> >& CK );
00241 template void BezierCurveDerivatives(
00242           const double u, const int p,
00243           const Ptr< double >& U, const Ptr< hpoint<double> >& Pw, const int d,
00244           Ptr< point<double> >& CK );
00245 
00246 template void BezierCurveDerivatives(
00247          const float u, const int p,
00248          const Ptr< float >& U, const Ptr< hpoint2<float> >& Pw, const int d,
00249          Ptr< point2<float> >& CK );
00250 template void BezierCurveDerivatives(
00251          const double u, const int p,
00252          const Ptr< double >& U, const Ptr< hpoint2<double> >& Pw, const int d,
00253          Ptr< point2<double> >& CK );
00254 
00255 /*-------------------------------------------------------------------------
00256   Calculates the first 'd' mixed partial derivatives of the projection of a
00257   NURBS surface into euclidian space (3-dimensions), so the calculated ders
00258   are points in 3-dimensional space. They are returned in 'SKL[k][l]'.  
00259   (see "The NURBS Book")
00260 ------------------------------------------------------------------------- */
00261 template< class T, class HP, class EP >          
00262 void BezierSurfaceDerivatives(
00263                 const T u, const T v,
00264                 const int pu, const Ptr< T >& U,
00265                 const int pv, const Ptr< T >& V,
00266                 const Ptr< Ptr < HP > >& Pw,
00267                 const int d, Ptr< Ptr < EP > >& SKL )
00268 {
00269   int i,j,k,l;
00270   EP v1,v2,vh;
00271   T w00;
00272   Ptr< Ptr < HP > > SKLh;
00273   
00274   SKLh.reserve_place( reserve_stack(Ptr < HP >,d+1), d+1 );
00275   for( i = 0; i < d+1; i++ )
00276     SKLh[i].reserve_place( reserve_stack(HP,d+1), d+1 );
00277     
00278   BezierBSPSurfaceDerivatives<T,HP>( u, v, pu, U, pv, V, Pw, d, SKLh );
00279 
00280   w00 = SKLh[0][0].weight();
00281   
00282   for( k = 0; k <= d; k++ )
00283   {
00284     for( l = 0; l <= d-k; l++ )
00285     {
00286       v1 = ortho( SKLh[k][l] );
00287 
00288       for( j = 1; j <= l; j++ )
00289       {
00290         vh = (rtr<T>::BinCoeff(l,j) * SKLh[0][j].weight()) * SKL[k][l-j]; 
00291         v1 = v1 - vh;
00292       }  
00293       for( i = 1; i <= k; i++ )
00294       {
00295         vh = (rtr<T>::BinCoeff(k,i) * SKLh[i][0].weight()) * SKL[k-i][l];
00296         v1 = v1 - vh;
00297 
00298         set( v2, (T)0.0 );
00299         for( j = 1; j <= l; j++ )
00300         {
00301           vh = (rtr<T>::BinCoeff(l,j) * SKLh[i][j].weight()) * SKL[k-i][l-j];
00302           v2 = v2 + vh;
00303         }
00304         vh =  rtr<T>::BinCoeff(k,i) * v2;
00305         v1 = v1 - vh;
00306       }
00307       SKL[k][l] = ((T)1.0 / w00) * v1;
00308     }    
00309   }
00310 }
00311 
00312 // template instantiation
00313 template void BezierSurfaceDerivatives(
00314                 const float u, const float v,
00315                 const int pu, const Ptr< float >& U,
00316                 const int pv, const Ptr< float >& V,
00317                 const Ptr< Ptr < hpoint<float> > >& Pw,
00318                 const int d, Ptr< Ptr < point<float> > >& SKL );
00319 template void BezierSurfaceDerivatives(
00320                 const double u, const double v,
00321                 const int pu, const Ptr< double >& U,
00322                 const int pv, const Ptr< double >& V,
00323                 const Ptr< Ptr < hpoint<double> > >& Pw,
00324                 const int d, Ptr< Ptr < point<double> > >& SKL );
00325 
00326 template void BezierSurfaceDerivatives(
00327                 const float u, const float v,
00328                 const int pu, const Ptr< float >& U,
00329                 const int pv, const Ptr< float >& V,
00330                 const Ptr< Ptr < hpoint1<float> > >& Pw,
00331                 const int d, Ptr< Ptr < point1<float> > >& SKL );
00332 template void BezierSurfaceDerivatives(
00333                 const double u, const double v,
00334                 const int pu, const Ptr< double >& U,
00335                 const int pv, const Ptr< double >& V,
00336                 const Ptr< Ptr < hpoint1<double> > >& Pw,
00337                 const int d, Ptr< Ptr < point1<double> > >& SKL );
00338 
00339 #ifdef _MSC_VER
00340 template void BezierSurfaceDerivatives(
00341                 const float u, const float v,
00342                 const int pu, const Ptr< float >& U,
00343                 const int pv, const Ptr< float >& V,
00344                 const Ptr< Ptr < point<float> > >& Pw,
00345                 const int d, Ptr< Ptr < point<float> > >& SKL );
00346 template void BezierSurfaceDerivatives(
00347                 const double u, const double v,
00348                 const int pu, const Ptr< double >& U,
00349                 const int pv, const Ptr< double >& V,
00350                 const Ptr< Ptr < point<double> > >& Pw,
00351                 const int d, Ptr< Ptr < point<double> > >& SKL );
00352 
00353 template void BezierSurfaceDerivatives(
00354                 const float u, const float v,
00355                 const int pu, const Ptr< float >& U,
00356                 const int pv, const Ptr< float >& V,
00357                 const Ptr< Ptr < point1<float> > >& Pw,
00358                 const int d, Ptr< Ptr < point1<float> > >& SKL );
00359 template void BezierSurfaceDerivatives(
00360                 const double u, const double v,
00361                 const int pu, const Ptr< double >& U,
00362                 const int pv, const Ptr< double >& V,
00363                 const Ptr< Ptr < point1<double> > >& Pw,
00364                 const int d, Ptr< Ptr < point1<double> > >& SKL );
00365 #endif
00366 
00367 }
00368 
00369 
00370 
00371 

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