00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00047
00048
00049
00050
00051
00052
00053
00054
00055
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 );
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
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
00107
00108
00109
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
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
00203
00204
00205
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
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
00257
00258
00259
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
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