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

gunu_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_float.h"
00026 #include "gul_vector.h"
00027 #include "guar_bincoeff.h"
00028 #include "gunu_basics.h"
00029 #include "gunu_derivatives.h"
00030 
00031 
00032 namespace gunu {
00033 
00034 using gul::rtr;
00035 using gul::Ptr;
00036 using gul::point;
00037 using gul::point1;
00038 using gul::point2;
00039 using gul::hpoint;
00040 using gul::hpoint1;
00041 using gul::hpoint2;
00042 using gul::set;
00043 using gul::euclid;
00044 using gul::ortho;
00045 using gul::Min;
00046 using gul::Max;
00047 using gul::cross_product;
00048 using gul::normalize;
00049 using gul::rel_equal;
00050 
00051 /*------------------------------------------------------------------------
00052   Calculate NURBS basis functions and their first 'n' derivatives.
00053   Only the non-vanishing basis functions are calculated (see "The NURBS Book")
00054 ------------------------------------------------------------------------*/  
00055 template< class T >
00056 void CalcDersBasisFuns( 
00057             const T u, const int i, const int p, const int n,
00058             const Ptr< T >& U, Ptr< Ptr< T > >& ders )
00059 {
00060   T saved,temp,d;
00061   int j,k,r,s1,s2,rk,pk,j1,j2;
00062 
00063   Ptr< Ptr< T > > ndu,a;
00064   Ptr< T > left,right;
00065   
00066   ndu.reserve_place( reserve_stack(Ptr< T >,p+1), p+1 );
00067   for( j = 0; j < p+1; j++ )
00068     ndu[j].reserve_place( reserve_stack(T,p+1), p+1 );
00069  
00070   a.reserve_place( reserve_stack(Ptr< T >,2), 2 );
00071   for( j = 0; j < 2; j++ )
00072     a[j].reserve_place( reserve_stack(T,p+1), p+1 );
00073 
00074   left.reserve_place( reserve_stack(T,p+1), p+1 );
00075   right.reserve_place( reserve_stack(T,p+1), p+1 );
00076   
00077   ndu[0][0] = 1.0;
00078   
00079   for( j = 1; j <= p; j++ )
00080   {
00081     left[j] = u - U[i+1-j];
00082     right[j] = U[i+j]-u;
00083     saved = 0.0;
00084     for( r = 0; r < j; r++ )
00085     {
00086       ndu[j][r] = right[r+1] + left[j-r];
00087       temp = ndu[r][j-1]/ndu[j][r];
00088       
00089       ndu[r][j] = saved + right[r+1]*temp;
00090       saved = left[j-r]*temp;
00091     }
00092     ndu[j][j] = saved;
00093   }
00094 
00095   
00096   for( j = 0; j <= p; j++ )
00097   {
00098     ders[0][j] = ndu[j][p];        /* Basis Funktionen = 0.Ableitung */
00099   }
00100 
00101   for( r = 0; r <= p; r++ )
00102   {
00103     s1 = 0;    s2 = 1;
00104     a[0][0] = 1.0;
00105 
00106     for( k = 1; k <= n; k++ )
00107     {
00108       d = 0.0;
00109       rk = r-k;  pk = p-k;
00110       
00111       if( r >= k )
00112       {
00113         a[s2][0] = a[s1][0] / ndu[pk+1][rk];
00114         d = a[s2][0] * ndu[rk][pk];
00115       }  
00116       if( rk >= -1 )
00117         j1 = 1;
00118       else
00119         j1 = -rk;  
00120       if( r-1 <= pk )
00121         j2 = k-1;
00122       else
00123         j2 = p-r;  
00124 
00125       for( j = j1; j <= j2; j++ )
00126       {
00127         a[s2][j] = (a[s1][j] - a[s1][j-1]) / ndu[pk+1][rk+j];
00128         d += a[s2][j] * ndu[rk+j][pk];
00129       }  
00130       if( r <= pk )
00131       {
00132         a[s2][k] = -a[s1][k-1] / ndu[pk+1][r];
00133         d += a[s2][k] * ndu[r][pk];
00134       }  
00135       ders[k][r] = d;
00136       j = s1; s1 = s2; s2 = j;
00137     }        
00138   }
00139   
00140   r = p;
00141   for( k = 1; k <= n; k++ )
00142   {
00143     for( j = 0; j <= p; j++ )
00144       ders[k][j] *= (T)r;
00145     r *= p-k;
00146   }    
00147 }
00148 // template instantiation
00149 template void CalcDersBasisFuns( 
00150           const float u, const int i, const int p, const int n, 
00151           const Ptr<float>& U, Ptr< Ptr<float> >& ders );
00152 template void CalcDersBasisFuns( 
00153           const double u, const int i, const int p, const int n,
00154           const Ptr<double>& U, Ptr< Ptr<double> >& ders );
00155 
00156 /*-------------------------------------------------------------------------
00157   Calculates the first 'd' derivatives of a curve at a point 'u'. The results
00158   are homogeneous points (like the control points), returned in 'CK[]'
00159   (see "The NURBS Book")
00160 --------------------------------------------------------------------------- */  
00161 template< class T, class EP >
00162 GULAPI void BSPCurveDerivatives( 
00163            const T u, const int n, const int p, const gul::Ptr< T >& U,
00164            const gul::Ptr< EP >& Pw, const int d, gul::Ptr< EP >& CK )
00165 {
00166   int du,k,j,span;
00167   EP v1;
00168   Ptr< Ptr< T > > ders;
00169     
00170   du = Min( d, p );
00171 
00172   ders.reserve_place( reserve_stack(Ptr< T >,du+1), du+1 );
00173   for( j = 0; j <du+1; j++ )
00174     ders[j].reserve_place( reserve_stack(T,p+1), p+1 );
00175 
00176   for( k = p+1; k <= d; k++ )
00177     set( CK[k], (T)0.0 );   /* Ableitungen > Grad = 0 */
00178 
00179   span = FindSpan( u, n, p, U );
00180   CalcDersBasisFuns( u, span, p, du, U, ders );
00181   
00182   for( k = 0; k <= du; k++ )
00183   {
00184     set( CK[k], (T)0.0 );
00185     for( j = 0; j <= p; j++ )
00186     {
00187       v1 = ders[k][j] * Pw[span-p+j];
00188       CK[k] = CK[k] + v1;
00189     }
00190   }
00191 }  
00192 // template instantiation
00193 template GULAPI void BSPCurveDerivatives( 
00194      const float u, const int n, const int p, const Ptr< float >& U,
00195      const Ptr< point<float> >& Pw, const int d, Ptr< point<float> >& CK );
00196 template GULAPI void BSPCurveDerivatives( 
00197       const double u, const int n, const int p, const Ptr< double >& U,
00198       const Ptr< point<double> >& Pw, const int d, Ptr< point<double> >& CK );
00199 template GULAPI void BSPCurveDerivatives( 
00200        const float u, const int n, const int p, const Ptr< float >& U,
00201        const Ptr< point2<float> >& Pw, const int d, Ptr< point2<float> >& CK );
00202 template GULAPI void BSPCurveDerivatives( 
00203       const double u, const int n, const int p, const Ptr< double >& U,
00204       const Ptr< point2<double> >& Pw, const int d, Ptr< point2<double> >& CK );
00205 
00206 /*---------------------------------------------------------------------------
00207   Calculates mixed partial derivatives of a NURBS surface. Let 'k' and 'l' be
00208   the number of derivatives in 'u' and 'v' direction, then all mixed ders with
00209   'k+l <= d' are calculated. They are returned in 'SKL[k][l]'.  
00210   (see "The NURBS Book")
00211 ------------------------------------------------------------------------- */  
00212 template< class T, class EP >
00213 void BSPSurfaceDerivatives(
00214                 const T u, const T v,
00215                 const int nu, const int pu, const Ptr< T >& U,
00216                 const int nv, const int pv, const Ptr< T >& V,
00217                 const Ptr< Ptr< EP > >& Pw,
00218                 const int d, Ptr< Ptr< EP > >& SKL )
00219 {                
00220   int du,dv,k,l,uspan,vspan,s,r,dd;
00221   EP v1;
00222   Ptr< EP > temp;
00223   Ptr< Ptr< T > > Nu,Nv;
00224 
00225   du = Min( d, pu );
00226   dv = Min( d, pv );
00227 
00228   Nu.reserve_place( reserve_stack(Ptr< T >,du+1), du+1 );
00229   for( k = 0; k < pu+1; k++ )
00230     Nu[k].reserve_place( reserve_stack(T,pu+1), pu+1 );
00231 
00232   Nv.reserve_place( reserve_stack(Ptr< T >,dv+1), dv+1 );
00233   for( k = 0; k < pv+1; k++ )
00234     Nv[k].reserve_place( reserve_stack(T,pv+1), pv+1 );
00235 
00236   temp.reserve_place( reserve_stack(EP,pv+1), pv+1 );
00237 
00238   for( k = pu+1; k <= d; k++ )
00239     for( l = 0; l <= d - k; l++ )
00240       set( SKL[k][l], (T)0.0 );
00241       
00242   for( l = pv+1; l <= d; l++ )
00243     for( k = 0; k <= d - l; k++ )
00244       set( SKL[k][l], (T)0.0 );
00245       
00246   uspan = FindSpan( u, nu, pu, U );
00247   CalcDersBasisFuns( u, uspan, pu, du, U, Nu );
00248  
00249   vspan = FindSpan( v, nv, pv, V );
00250   CalcDersBasisFuns( v, vspan, pv, dv, V, Nv );
00251   
00252   for( k = 0; k <= du; k++ )
00253   {
00254     for( s = 0; s <= pv; s++ )
00255     {
00256       set( temp[s], (T)0.0 );
00257       for( r = 0; r <= pu; r++ )
00258       {
00259         v1 = Nu[k][r] * Pw[vspan-pv+s][uspan-pu+r];
00260         temp[s] = temp[s] + v1;
00261       }  
00262     }
00263     dd = Min( d - k, dv );
00264     for( l = 0; l <= dd; l++ )
00265     {
00266       set( SKL[k][l], (T)0.0 );
00267       for( s = 0; s <= pv; s++ )
00268       {
00269         v1 = Nv[l][s] * temp[s];
00270         SKL[k][l] = SKL[k][l] + v1;
00271       }
00272     }
00273   }
00274 }  
00275 // template instantiation
00276 template void BSPSurfaceDerivatives(
00277                 const float u, const float v,
00278                 const int nu, const int pu, const Ptr< float >& U,
00279                 const int nv, const int pv, const Ptr< float >& V,
00280                 const Ptr< Ptr< point<float> > >& Pw,
00281                 const int d, Ptr< Ptr< point<float> > >& SKL );           
00282 template void BSPSurfaceDerivatives(
00283                 const double u, const double v,
00284                 const int nu, const int pu, const Ptr< double >& U,
00285                 const int nv, const int pv, const Ptr< double >& V,
00286                 const Ptr< Ptr< point<double> > >& Pw,
00287                 const int d, Ptr< Ptr< point<double> > >& SKL );
00288 
00289 template void BSPSurfaceDerivatives(
00290                 const float u, const float v,
00291                 const int nu, const int pu, const Ptr< float >& U,
00292                 const int nv, const int pv, const Ptr< float >& V,
00293                 const Ptr< Ptr< hpoint<float> > >& Pw,
00294                 const int d, Ptr< Ptr< hpoint<float> > >& SKL );           
00295 template void BSPSurfaceDerivatives(
00296                 const double u, const double v,
00297                 const int nu, const int pu, const Ptr< double >& U,
00298                 const int nv, const int pv, const Ptr< double >& V,
00299                 const Ptr< Ptr< hpoint<double> > >& Pw,
00300                 const int d, Ptr< Ptr< hpoint<double> > >& SKL );
00301 
00302 /*-------------------------------------------------------------------------
00303   Calculates the first 'd' partial derivatives of the projection of a NURBS
00304   curve into euclidian space (3-dimensions), so the calculated ders are points
00305   in 3-dimensional space   
00306   (see "The NURBS Book")
00307 ------------------------------------------------------------------------- */  
00308 template< class T, class HP, class EP >
00309 GULAPI void CurveDerivatives(
00310                     const T u, const int n, const int p,
00311                     const Ptr< T >& U, const Ptr< HP >& Pw, const int d,
00312                     Ptr< EP >& CK )             
00313 {
00314   Ptr< HP > CKh;
00315   EP v,v1;
00316   T w0;
00317   int k,i;
00318 
00319   CKh.reserve_place( reserve_stack(HP,d+1), d+1 );
00320      
00321   BSPCurveDerivatives<T,HP>( u, n, p, U, Pw, d, CKh );
00322 
00323   w0 = CKh[0].w;
00324   
00325   for( k = 0; k <= d; k++ )
00326   {
00327     v = ortho( CKh[k] );
00328     
00329     for( i = 1; i <= k; i++ )
00330     {
00331       v1 = (rtr<T>::BinCoeff(k,i) * CKh[i].w) * CK[k-i];
00332       v = v - v1;
00333     }
00334     CK[k] = ((T)1.0 / w0) * v;       
00335   }
00336 }
00337 // template instantiation
00338 template GULAPI void CurveDerivatives(
00339           const float u, const int n, const int p,
00340           const Ptr< float >& U, const Ptr< hpoint<float> >& Pw, const int d,
00341           Ptr< point<float> >& CK );
00342 template GULAPI void CurveDerivatives(
00343           const double u, const int n, const int p,
00344           const Ptr< double >& U, const Ptr< hpoint<double> >& Pw, const int d,
00345           Ptr< point<double> >& CK );
00346 
00347 template GULAPI void CurveDerivatives(
00348          const float u, const int n, const int p,
00349          const Ptr< float >& U, const Ptr< hpoint2<float> >& Pw, const int d,
00350          Ptr< point2<float> >& CK );
00351 template GULAPI void CurveDerivatives(
00352          const double u, const int n, const int p,
00353          const Ptr< double >& U, const Ptr< hpoint2<double> >& Pw, const int d,
00354          Ptr< point2<double> >& CK );
00355 
00356 // VC currently (VC7) has problems with the ordering of function templates,
00357 // so i have to declare the following as specializations
00358 #ifdef _MSC_VER
00359 template<> GULAPI void CurveDerivatives(
00360      const float u, const int n, const int p,
00361      const gul::Ptr<float>& U, const gul::Ptr<gul::point2<float> >& Pw, 
00362      const int d, gul::Ptr<gul::point2<float> >& CK )  
00363 {
00364   BSPCurveDerivatives(u,n,p,U,Pw,d,CK);
00365 }
00366 template<> GULAPI void CurveDerivatives(
00367      const double u, const int n, const int p,
00368      const gul::Ptr<double>& U, const gul::Ptr<gul::point2<double> >& Pw, 
00369      const int d, gul::Ptr<gul::point2<double> >& CK )  
00370 {
00371   BSPCurveDerivatives(u,n,p,U,Pw,d,CK);
00372 }
00373 template<> GULAPI void CurveDerivatives(
00374      const float u, const int n, const int p,
00375      const gul::Ptr<float>& U, const gul::Ptr<gul::point<float> >& Pw, 
00376      const int d, gul::Ptr<gul::point<float> >& CK )  
00377 {
00378   BSPCurveDerivatives(u,n,p,U,Pw,d,CK);
00379 }
00380 template<> GULAPI void CurveDerivatives(
00381      const double u, const int n, const int p,
00382      const gul::Ptr<double>& U, const gul::Ptr<gul::point<double> >& Pw, 
00383      const int d, gul::Ptr<gul::point<double> >& CK )  
00384 {
00385   BSPCurveDerivatives(u,n,p,U,Pw,d,CK);
00386 }
00387 #endif
00388 
00389 /*-------------------------------------------------------------------------
00390   Calculates the first 'd' mixed partial derivatives of the projection of a
00391   NURBS surface into euclidian space (3-dimensions), so the calculated ders
00392   are points in 3-dimensional space. They are returned in 'SKL[k][l]'.  
00393   (see "The NURBS Book")
00394 ------------------------------------------------------------------------- */
00395 template< class T, class HP, class EP >          
00396 void SurfaceDerivatives(
00397                 const T u, const T v,
00398                 const int nu, const int pu, const Ptr< T >& U,
00399                 const int nv, const int pv, const Ptr< T >& V,
00400                 const Ptr< Ptr < HP > >& Pw,
00401                 const int d, Ptr< Ptr < EP > >& SKL )
00402 {
00403   int i,j,k,l;
00404   EP v1,v2,vh;
00405   T w00;
00406   Ptr< Ptr < HP > > SKLh;
00407   
00408   SKLh.reserve_place( reserve_stack(Ptr < HP >,d+1), d+1 );
00409   for( i = 0; i < d+1; i++ )
00410     SKLh[i].reserve_place( reserve_stack(HP,d+1), d+1 );
00411     
00412   BSPSurfaceDerivatives<T,HP>( u, v, nu, pu, U, nv, pv, V, Pw, d, SKLh );
00413 
00414   w00 = SKLh[0][0].w;
00415   
00416   for( k = 0; k <= d; k++ )
00417   {
00418     for( l = 0; l <= d-k; l++ )
00419     {
00420       v1 = ortho( SKLh[k][l] );
00421 
00422       for( j = 1; j <= l; j++ )
00423       {
00424         vh = (rtr<T>::BinCoeff(l,j) * SKLh[0][j].w) * SKL[k][l-j]; 
00425         v1 = v1 - vh;
00426       }  
00427       for( i = 1; i <= k; i++ )
00428       {
00429         vh = (rtr<T>::BinCoeff(k,i) * SKLh[i][0].w) * SKL[k-i][l];
00430         v1 = v1 - vh;
00431 
00432         set( v2, (T)0.0 );
00433         for( j = 1; j <= l; j++ )
00434         {
00435           vh = (rtr<T>::BinCoeff(l,j) * SKLh[i][j].w) * SKL[k-i][l-j];
00436           v2 = v2 + vh;
00437         }
00438         vh =  rtr<T>::BinCoeff(k,i) * v2;
00439         v1 = v1 - vh;
00440       }
00441       SKL[k][l] = ((T)1.0 / w00) * v1;
00442     }    
00443   }
00444 }
00445 // template instantiation
00446 template void SurfaceDerivatives(
00447                 const float u, const float v,
00448                 const int nu, const int pu, const Ptr< float >& U,
00449                 const int nv, const int pv, const Ptr< float >& V,
00450                 const Ptr< Ptr < hpoint<float> > >& Pw,
00451                 const int d, Ptr< Ptr < point<float> > >& SKL );
00452 template void SurfaceDerivatives(
00453                 const double u, const double v,
00454                 const int nu, const int pu, const Ptr< double >& U,
00455                 const int nv, const int pv, const Ptr< double >& V,
00456                 const Ptr< Ptr < hpoint<double> > >& Pw,
00457                 const int d, Ptr< Ptr < point<double> > >& SKL );
00458 
00459 template void SurfaceDerivatives(
00460                 const float u, const float v,
00461                 const int nu, const int pu, const Ptr< float >& U,
00462                 const int nv, const int pv, const Ptr< float >& V,
00463                 const Ptr< Ptr < hpoint1<float> > >& Pw,
00464                 const int d, Ptr< Ptr < point1<float> > >& SKL );
00465 template void SurfaceDerivatives(
00466                 const double u, const double v,
00467                 const int nu, const int pu, const Ptr< double >& U,
00468                 const int nv, const int pv, const Ptr< double >& V,
00469                 const Ptr< Ptr < hpoint1<double> > >& Pw,
00470                 const int d, Ptr< Ptr < point1<double> > >& SKL );
00471 
00472 /*---------------------------------------------------------------------
00473   Calculates the normal vector of a NURBS surface at u=0,v=0
00474 ---------------------------------------------------------------------*/
00475 
00476 template< class T, class HP >
00477 void CalcNormal_U0V0(
00478           const int nu, const int pu,
00479           const int nv, const int pv,
00480           const Ptr<Ptr<HP> >& Pw, point<T> *Normal )
00481 {
00482   int i,j,k,m;
00483   point<T> v1,v2,a,b;
00484 
00485   set(a,(T)0);
00486   set(b,(T)0);
00487 
00488   m = Max(pu,pv);
00489   
00490   for( k=0; k<m; k++ )
00491   {
00492     i=0;
00493     j=k+1;
00494     
00495     while( i <= k )
00496     {
00497       if( (i <= pv) && (j <= pu) )
00498       {
00499         v1 = euclid( Pw[i][j] );
00500         v2 = euclid( Pw[i][0] );
00501         a = v1 - v2;
00502         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00503         {
00504           k = m;     // Vektor in Tangetialebene gefunden, fertig
00505           break;
00506         }
00507       }
00508       i++;
00509       j--;  
00510     }
00511   }
00512 
00513   for( k=0; k<m; k++ )
00514   {
00515     i=0;
00516     j=k+1;
00517     
00518     while( i <= k )
00519     {
00520       if( (j <= pv) && (i <= pu) )
00521       {
00522         v1 = euclid( Pw[j][i] );
00523         v2 = euclid( Pw[0][i] );
00524         b = v1 - v2;
00525         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00526         {
00527           k = m;     // Vektor in Tangetialebene gefunden, fertig
00528           break;
00529         }
00530       }
00531       i++;
00532       j--;  
00533     }
00534   }
00535 
00536   v1 = cross_product( a, b );
00537   normalize( Normal, v1 );
00538 }
00539 // template instantiation
00540 template void CalcNormal_U0V0( 
00541            const int nu, const int pu, 
00542            const int nv, const int pv,
00543            const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *Normal );
00544 template void CalcNormal_U0V0( 
00545            const int nu, const int pu, 
00546            const int nv, const int pv,
00547            const Ptr< Ptr< point<float> > >& Pw, point<float> *Normal );
00548 
00549 template void CalcNormal_U0V0( 
00550            const int nu, const int pu, 
00551            const int nv, const int pv,
00552            const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *Normal );
00553 template void CalcNormal_U0V0( 
00554            const int nu, const int pu, 
00555            const int nv, const int pv,
00556            const Ptr< Ptr< point<double> > >& Pw, point<double> *Normal );
00557 
00558 /*---------------------------------------------------------------------
00559   Calculates the normal vector of a NURBS surface at u=1,v=0
00560 ---------------------------------------------------------------------*/
00561 template< class T, class HP >
00562 void CalcNormal_U1V0( 
00563            const int nu, const int pu, 
00564            const int nv, const int pv,
00565            const Ptr< Ptr< HP > >& Pw, point<T> *Normal  )
00566 {
00567   int i,j,k,m;
00568   point<T> v1,v2,a,b;
00569 
00570   set(a,(T)0);
00571   set(b,(T)0);
00572 
00573   m = Max(pu,pv);
00574   
00575   for( k=0; k<m; k++ )
00576   {
00577     i=0;
00578     j=k+1;
00579     
00580     while( i <= k )
00581     {
00582       if( (i <= pv) && (j <= pu) )
00583       {
00584         v1 = euclid( Pw[i][nu] );
00585         v2 = euclid( Pw[i][nu-j] );
00586         a =  v1 - v2;
00587         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00588         {
00589           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00590           break;
00591         }
00592       }
00593       i++;
00594       j--;  
00595     }
00596   }
00597 
00598   for( k=0; k<m; k++ )
00599   {
00600     i=0;
00601     j=k+1;
00602     
00603     while( i <= k )
00604     {
00605       if( (j <= pv) && (i <= pu) )
00606       {
00607         v1 = euclid( Pw[j][nu-i] );
00608         v2 = euclid( Pw[0][nu-i] );
00609         b = v1 - v2;
00610         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00611         {
00612           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00613           break;
00614         }
00615       }
00616       i++;
00617       j--;  
00618     }
00619   }
00620 
00621   v1 = cross_product( a, b );
00622   normalize( Normal, v1 );
00623 }
00624 // template instantiation
00625 template void CalcNormal_U1V0( 
00626            const int nu, const int pu, 
00627            const int nv, const int pv,
00628            const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *Normal );
00629 template void CalcNormal_U1V0( 
00630            const int nu, const int pu, 
00631            const int nv, const int pv,
00632            const Ptr< Ptr< point<float> > >& Pw, point<float> *Normal );
00633 
00634 template void CalcNormal_U1V0( 
00635            const int nu, const int pu, 
00636            const int nv, const int pv,
00637            const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *Normal );
00638 template void CalcNormal_U1V0( 
00639            const int nu, const int pu, 
00640            const int nv, const int pv,
00641            const Ptr< Ptr< point<double> > >& Pw, point<double> *Normal );
00642 
00643 
00644 /*---------------------------------------------------------------------
00645   Calculates the normal vector of a NURBS surface at u=0,v=1
00646 ---------------------------------------------------------------------*/
00647 template< class T, class HP >
00648 void CalcNormal_U0V1( 
00649            const int nu, const int pu, 
00650            const int nv, const int pv,
00651            const Ptr< Ptr< HP > >& Pw, point<T> *Normal  )
00652 {
00653   int i,j,k,m;
00654   point<T> v1,v2,a,b;
00655 
00656   set(a,(T)0);
00657   set(b,(T)0);
00658   
00659   m = Max(pu,pv);
00660   
00661   for( k=0; k<m; k++ )
00662   {
00663     i=0;
00664     j=k+1;
00665     
00666     while( i <= k )
00667     {
00668       if( (i <= pv) && (j <= pu) )
00669       {
00670         v1 = euclid( Pw[nv-i][j] );
00671         v2 = euclid( Pw[nv-i][0] );
00672         a = v1 - v2;
00673         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00674         {
00675           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00676           break;
00677         }       
00678       }
00679       i++;
00680       j--;  
00681     }
00682   }
00683 
00684   for( k=0; k<m; k++ )
00685   {
00686     i=0;
00687     j=k+1;
00688     
00689     while( i <= k )
00690     {
00691       if( (j <= pv) && (i <= pu) )
00692       {
00693         v1 = euclid( Pw[nv][i] );
00694         v2 = euclid( Pw[nv-j][i] );
00695         b =  v1 - v2;
00696         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00697         {
00698           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00699           break;
00700         }
00701       }
00702       i++;
00703       j--;  
00704     }
00705   }
00706 
00707   v1 = cross_product( a, b );
00708   normalize( Normal, v1 );
00709 }
00710 // template instantiation
00711 template void CalcNormal_U0V1( 
00712            const int nu, const int pu, 
00713            const int nv, const int pv,
00714            const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *Normal );
00715 template void CalcNormal_U0V1( 
00716            const int nu, const int pu, 
00717            const int nv, const int pv,
00718            const Ptr< Ptr< point<float> > >& Pw, point<float> *Normal );
00719 
00720 template void CalcNormal_U0V1( 
00721            const int nu, const int pu, 
00722            const int nv, const int pv,
00723            const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *Normal );
00724 template void CalcNormal_U0V1( 
00725            const int nu, const int pu, 
00726            const int nv, const int pv,
00727            const Ptr< Ptr< point<double> > >& Pw, point<double> *Normal );
00728 
00729 
00730 /*---------------------------------------------------------------------
00731   Calculates the normal vector of a NURBS surface at u=1,v=1
00732 ---------------------------------------------------------------------*/
00733 template< class T, class HP >
00734 void CalcNormal_U1V1( 
00735            const int nu, const int pu, 
00736            const int nv, const int pv,
00737            const Ptr< Ptr< HP > >& Pw, point<T> *Normal  )
00738 {
00739   int i,j,k,m;
00740   point<T> v1,v2,a,b;
00741 
00742   set(a,(T)0);
00743   set(b,(T)0);
00744   
00745   m = Max(pu,pv);
00746   
00747   for( k=0; k<m; k++ )
00748   {
00749     i=0;
00750     j=k+1;
00751     
00752     while( i <= k )
00753     {
00754       if( (i <= pv) && (j <= pu) )
00755       {
00756         v1 = euclid( Pw[nv-i][nu] );
00757         v2 = euclid( Pw[nv-i][nu-j] );
00758         a = v1 - v2;
00759         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00760         {
00761           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00762           break;
00763         }
00764       }
00765       i++;
00766       j--;  
00767     }
00768   }
00769 
00770   for( k=0; k<m; k++ )
00771   {
00772     i=0;
00773     j=k+1;
00774     
00775     while( i <= k )
00776     {
00777       if( (j <= pv) && (i <= pu) )
00778       {
00779         v1 = euclid( Pw[nv][nu-i] );
00780         v2 = euclid( Pw[nv-j][nu-i] );
00781         b = v1 - v2;
00782         if( !rel_equal(v1,v2,rtr<T>::zero_tol()) )
00783         {
00784           k = m;     /* Vektor in Tangetialebene gefunden, fertig */
00785           break;
00786         }
00787       }
00788       i++;
00789       j--;  
00790     }
00791   }
00792 
00793   v1 = cross_product( a, b );
00794   normalize( Normal, v1 );
00795 }
00796 // template instantiation
00797 template void CalcNormal_U1V1( 
00798            const int nu, const int pu, 
00799            const int nv, const int pv,
00800            const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *Normal );
00801 template void CalcNormal_U1V1( 
00802            const int nu, const int pu, 
00803            const int nv, const int pv,
00804            const Ptr< Ptr< point<float> > >& Pw, point<float> *Normal );
00805 
00806 template void CalcNormal_U1V1( 
00807            const int nu, const int pu, 
00808            const int nv, const int pv,
00809            const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *Normal );
00810 template void CalcNormal_U1V1( 
00811            const int nu, const int pu, 
00812            const int nv, const int pv,
00813            const Ptr< Ptr< point<double> > >& Pw, point<double> *Normal );
00814 
00815 }
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 

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