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 "gul_matrix.h"
00027 #include "guge_normalize.h"
00028 #include "guma_minimize.h"
00029 #include "gunu_basics.h"
00030 #include "gunu_refine.h"
00031 #include "gunu_make_compatible.h"
00032 #include "gunu_mba_approximate.h"
00033
00034 namespace gunu {
00035
00036 using gul::rtr;
00037 using gul::Max;
00038 using gul::Ptr;
00039 using gul::point;
00040 using gul::point1;
00041 using gul::point2;
00042 using gul::vec4;
00043 using gul::mat4x4;
00044 using guge::CalcBoundingBoxE;
00045 using guma::GoldenSectionSearch;
00046 using gul::set;
00047
00048
00049
00050
00051
00052
00053
00054 template< class T >
00055 void BAapproximate(
00056 int nP, Ptr< point<T> >& P,
00057 int nu, int pu, Ptr<T>& U,
00058 int nv, int pv, Ptr<T>& V,
00059 Ptr< Ptr< point1<T> > >& delta )
00060 {
00061 Ptr<T> Nu, Nv;
00062 Ptr< Ptr<T> > omega, w, w2;
00063 int i,j,k,l,C,uspan,vspan,uind,vind;
00064 T sum_w2;
00065
00066
00067
00068 omega.reserve_pool(nv+1);
00069 for( i = 0; i < nv+1; i++ )
00070 omega[i].reserve_pool(nu+1);
00071
00072 w.reserve_pool(pu+1);
00073 w2.reserve_pool(pu+1);
00074 for( i = 0; i < pu+1; i++ )
00075 {
00076 w[i].reserve_pool(pv+1);
00077 w2[i].reserve_pool(pv+1);
00078 }
00079 Nu.reserve_pool(pu+1);
00080 Nv.reserve_pool(pv+1);
00081
00082 for( j = 0; j <= nv; j++ )
00083 {
00084 for( i = 0; i <= nu; i++ )
00085 {
00086 delta[j][i].x = (T)0;
00087 omega[j][i] = (T)0;
00088 }
00089 }
00090 for( C = 0; C < nP; C++ )
00091 {
00092 uspan = FindSpan( P[C].x, nu, pu, U );
00093 CalcBasisFunctions( P[C].x, uspan, pu, U, Nu );
00094
00095 vspan = FindSpan( P[C].y, nv, pv, V );
00096 CalcBasisFunctions( P[C].y, vspan, pv, V, Nv );
00097
00098 sum_w2 = (T)0;
00099 for( k = 0; k <= pu; k++ )
00100 {
00101 for( l = 0; l <= pv; l++ )
00102 {
00103 w[k][l] = Nu[k] * Nv[l];
00104 w2[k][l] = w[k][l] * w[k][l];
00105 sum_w2 += w2[k][l];
00106 }
00107 }
00108 uind = uspan - pu;
00109 vind = vspan - pv;
00110 for( k = 0; k <= pu; k++ )
00111 {
00112 for( l = 0; l <= pv; l++ )
00113 {
00114 delta[vind+l][uind+k].x += w2[k][l] * w[k][l] * P[C].z / sum_w2;
00115 omega[vind+l][uind+k] += w2[k][l];
00116 }
00117 }
00118 }
00119 for( j = 0; j <= nv; j++ )
00120 {
00121 for( i = 0; i <= nu; i++ )
00122 {
00123 if( omega[j][i] != (T)0 )
00124 delta[j][i].x /= omega[j][i];
00125 else
00126 delta[j][i].x = (T)0;
00127 }
00128 }
00129 }
00130 template void BAapproximate(
00131 int nP, Ptr< point<float> >& P,
00132 int nu, int pu, Ptr<float>& U,
00133 int nv, int pv, Ptr<float>& V,
00134 Ptr< Ptr< point1<float> > >& delta );
00135 template void BAapproximate(
00136 int nP, Ptr< point<double> >& P,
00137 int nu, int pu, Ptr<double>& U,
00138 int nv, int pv, Ptr<double>& V,
00139 Ptr< Ptr< point1<double> > >& delta );
00140
00141
00142
00143
00144
00145
00146
00147
00148 template< class T >
00149 void BAapproximate(
00150 int nP, Ptr< point<T> >& P, Ptr<T>& Sigma,
00151 int nu, int pu, Ptr<T>& U,
00152 int nv, int pv, Ptr<T>& V,
00153 Ptr< Ptr< point1<T> > >& delta )
00154 {
00155 Ptr<T> Nu, Nv;
00156 Ptr< Ptr<T> > omega, w, w2;
00157 int i,j,k,l,C,uspan,vspan,uind,vind;
00158 T factor, sum_w2;
00159
00160
00161
00162 omega.reserve_pool(nv+1);
00163 for( i = 0; i < nv+1; i++ )
00164 omega[i].reserve_pool(nu+1);
00165
00166 w.reserve_pool(pu+1);
00167 w2.reserve_pool(pu+1);
00168 for( i = 0; i < pu+1; i++ )
00169 {
00170 w[i].reserve_pool(pv+1);
00171 w2[i].reserve_pool(pv+1);
00172 }
00173 Nu.reserve_pool(pu+1);
00174 Nv.reserve_pool(pv+1);
00175
00176 for( j = 0; j <= nv; j++ )
00177 {
00178 for( i = 0; i <= nu; i++ )
00179 {
00180 delta[j][i].x = (T)0;
00181 omega[j][i] = (T)0;
00182 }
00183 }
00184 for( C = 0; C < nP; C++ )
00185 {
00186 uspan = FindSpan( P[C].x, nu, pu, U );
00187 CalcBasisFunctions( P[C].x, uspan, pu, U, Nu );
00188
00189 vspan = FindSpan( P[C].y, nv, pv, V );
00190 CalcBasisFunctions( P[C].y, vspan, pv, V, Nv );
00191
00192 sum_w2 = (T)0;
00193 for( k = 0; k <= pu; k++ )
00194 {
00195 for( l = 0; l <= pv; l++ )
00196 {
00197 w[k][l] = Nu[k] * Nv[l];
00198 w2[k][l] = w[k][l] * w[k][l];
00199 sum_w2 += w2[k][l];
00200 }
00201 }
00202 factor = (T)1 / (Sigma[C] * Sigma[C]);
00203
00204 uind = uspan - pu;
00205 vind = vspan - pv;
00206 for( k = 0; k <= pu; k++ )
00207 {
00208 for( l = 0; l <= pv; l++ )
00209 {
00210 w2[k][l] *= factor;
00211
00212 delta[vind+l][uind+k].x += w2[k][l] * w[k][l] * P[C].z / sum_w2;
00213 omega[vind+l][uind+k] += w2[k][l];
00214 }
00215 }
00216 }
00217 for( j = 0; j <= nv; j++ )
00218 {
00219 for( i = 0; i <= nu; i++ )
00220 {
00221 if( omega[j][i] != (T)0 )
00222 delta[j][i].x /= omega[j][i];
00223 else
00224 delta[j][i].x = (T)0;
00225 }
00226 }
00227 }
00228 template void BAapproximate(
00229 int nP, Ptr< point<float> >& P, Ptr<float>& Sigma,
00230 int nu, int pu, Ptr<float>& U,
00231 int nv, int pv, Ptr<float>& V,
00232 Ptr< Ptr< point1<float> > >& delta );
00233 template void BAapproximate(
00234 int nP, Ptr< point<double> >& P, Ptr<double>& Sigma,
00235 int nu, int pu, Ptr<double>& U,
00236 int nv, int pv, Ptr<double>& V,
00237 Ptr< Ptr< point1<double> > >& delta );
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 template< class T >
00255 void MBAapproximate(
00256 int nP, Ptr< point<T> >& P, bool useSigma, Ptr<T>& Sigma, int nIter,
00257 int pu, int pv, Ptr<T>& U, Ptr<T>& V, Ptr< Ptr< point1<T> > >& Psi )
00258 {
00259 Ptr<T> U1,V1,X;
00260 Ptr< Ptr< point1<T> > > Phi;
00261 int xp,i,j,nu,nv,s,maxSpans;
00262 point1<T> S;
00263 T d;
00264
00265 if( nIter < 1 ) return;
00266 maxSpans = 1 << (nIter-1);
00267
00268
00269
00270 U1.reserve_pool(pu + maxSpans + pu + 1);
00271 V1.reserve_pool(pv + maxSpans + pv + 1);
00272 i = Max(pu,pv);
00273 X.reserve_pool(i + maxSpans + i + 1);
00274
00275 Phi.reserve_pool(pv + maxSpans);
00276 for( i = 0; i < maxSpans + pv; i++ )
00277 Phi[i].reserve_pool(pu + maxSpans);
00278
00279
00280
00281 for( i = 0; i <= pu; i++ )
00282 {
00283 U[i] = (T)0;
00284 U[pu+1+i] = (T)1;
00285 }
00286 for( i = 0; i <= pv; i++ )
00287 {
00288 V[i] = (T)0;
00289 V[pv+1+i] = (T)1;
00290 }
00291
00292 for( j = 0; j <= pv; j++ )
00293 for( i = 0; i <= pu; i++ )
00294 set( Psi[j][i], (T)0 );
00295
00296 s = 1;
00297 nu = pu;
00298 nv = pv;
00299
00300 do
00301 {
00302 if( useSigma )
00303 BAapproximate( nP, P, Sigma, nu, pu, U, nv, pv, V, Phi );
00304 else
00305 BAapproximate( nP, P, nu, pu, U, nv, pv, V, Phi );
00306
00307 for( j = 0; j <= nv; j++ )
00308 for( i = 0; i <= nu; i++ )
00309 Psi[j][i].x += Phi[j][i].x;
00310
00311 for( i = 0; i < nP; i++ )
00312 {
00313 SurfacePoint( P[i].x, P[i].y, nu, pu, U, nv, pv, V, Phi, &S );
00314 P[i].z -= S.x;
00315 }
00316
00317 if( s >= maxSpans )
00318 break;
00319
00320 s <<= 1;
00321
00322 d = (T)1/(T)s;
00323 for( i = pu+1, xp = 0; i <= nu+1; i++, xp++ )
00324 X[xp] = U[i] - d;
00325 RefineSurface( nu, pu, U, nv, pv, V, Psi,
00326 X, xp-1, gul::u_direction, U1, V1, Phi );
00327 nu += xp;
00328
00329 for( i = pv+1, xp = 0; i <= nv+1; i++, xp++ )
00330 X[xp] = V[i] - d;
00331 RefineSurface( nu, pu, U1, nv, pv, V1, Phi,
00332 X, xp-1, gul::v_direction, U, V, Psi );
00333 nv += xp;
00334
00335 }while(1);
00336 }
00337 template void MBAapproximate(
00338 int nP, Ptr< point<float> >& P, bool useSigma, Ptr<float>& Sigma,
00339 int nIter, int pu, int pv, Ptr<float>& U, Ptr<float>& V,
00340 Ptr< Ptr< point1<float> > >& Psi );
00341 template void MBAapproximate(
00342 int nP, Ptr< point<double> >& P, bool useSigma, Ptr<double>& Sigma,
00343 int nIter, int pu, int pv, Ptr<double>& U, Ptr<double>& V,
00344 Ptr< Ptr< point1<double> > >& Psi );
00345
00346
00347
00348
00349
00350
00351
00352 template< class T >
00353 class minbbox_rec
00354 {
00355 public:
00356 Ptr< point<T> > P;
00357 int nP;
00358 T theta0_x;
00359 T theta0_y;
00360 T theta0_z;
00361
00362 minbbox_rec( int anP, Ptr< point<T> >& aP, T theta0x, T theta0y, T theta0z )
00363 {
00364 nP = anP; P = aP;
00365 theta0_x = theta0x; theta0_y = theta0y; theta0_z = theta0z;
00366 }
00367 T volume( T theta_x, T theta_y, T theta_z )
00368 {
00369 mat4x4<T> m1 = mat4x4<T>::rotate_x(theta0_x + theta_x);
00370 mat4x4<T> m2 = mat4x4<T>::rotate_y(theta0_y + theta_y);
00371 mat4x4<T> m3 = mat4x4<T>::rotate_z(theta0_z + theta_z);
00372 mat4x4<T> m;
00373 m = m1 * m2 * m3;
00374 vec4<T> v,vt;
00375 T minx,maxx,miny,maxy,minz,maxz;
00376
00377 v[0] = P[0].x; v[1] = P[0].y; v[2] = P[0].z; v[3] = 1.0;
00378 vt = v * m;
00379 minx = maxx = vt[0];
00380 miny = maxy = vt[1];
00381 minz = maxz = vt[2];
00382
00383 for( int i = 1; i < nP; i++ )
00384 {
00385 v[0] = P[i].x; v[1] = P[i].y; v[2] = P[i].z; v[3] = 1.0;
00386 vt = v * m;
00387 if( vt[0] < minx ) minx = vt[0];
00388 else if( vt[0] > maxx ) maxx = vt[0];
00389 if( vt[1] < miny ) miny = vt[1];
00390 else if( vt[1] > maxy ) maxy = vt[1];
00391 if( vt[2] < minz ) minz = vt[2];
00392 else if( vt[2] > maxz ) maxz = vt[2];
00393 }
00394 return (maxx-minx)*(maxy-miny)*(maxz-minz);
00395 }
00396 static T minimize_about_z_cb( T theta, void *data )
00397 {
00398 minbbox_rec *m = (minbbox_rec *)data;
00399 return m->volume( (T)0, (T)0, theta );
00400 }
00401 };
00402 template class minbbox_rec<float>;
00403 template class minbbox_rec<double>;
00404
00405
00406
00407
00408
00409
00410
00411
00412 template< class T >
00413 T MinimizeBBoxAboutZ( int nP, Ptr< point<T> >& P, T mintol, int maxits )
00414 {
00415 T minx,maxx,miny,maxy,minz,maxz,theta,V,V1;
00416 minbbox_rec<T> mr( nP, P, (T)0, (T)0, (T)0 );
00417
00418 CalcBoundingBoxE( nP, P, minx, maxx, miny, maxy, minz, maxz );
00419 V = (maxx-minx)*(maxy-miny)*(maxz-minz);
00420
00421 V1 = mr.volume( (T)0, (T)0, rtr<T>::golden_c() * rtr<T>::pi()/(T)2 );
00422 if( V1 < V )
00423 {
00424 GoldenSectionSearch(
00425 (T)0, rtr<T>::golden_c() * rtr<T>::pi()/(T)2, rtr<T>::pi()/(T)2,
00426 minbbox_rec<T>::minimize_about_z_cb, (void *)&mr,
00427 mintol*rtr<T>::pi()/(T)180, maxits, &theta,
00428 &V );
00429 }
00430 else
00431 theta = (T)0;
00432
00433 return theta;
00434 }
00435 template float MinimizeBBoxAboutZ( int nP, Ptr< point<float> >& P,
00436 float mintol, int maxits );
00437 template double MinimizeBBoxAboutZ( int nP, Ptr< point<double> >& P,
00438 double mintol, int maxits );
00439
00440
00441
00442
00443
00444
00445
00446
00447 template< class T, class HP >
00448 GULAPI void SurfaceOverXYPlane(
00449 int nDatPoints, Ptr< point<T> >& datPoints,
00450 bool useStdDevs, Ptr<T>& StdDevs,
00451 bool minimize, int nIter,
00452 int pu, int pv,
00453 int *ret_nu, Ptr<T> *retU,
00454 int *ret_nv, Ptr<T> *retV,
00455 Ptr< Ptr<HP> > *retPw )
00456 {
00457
00458 T minx,maxx,miny,maxy,minz,maxz;
00459 Ptr< point<T> > mbaPoints;
00460 int ref_nu, ref_nv, mba_nu, mba_nv, nu, nv;
00461 int ref_pu, ref_pv, mba_pu, mba_pv, i, j;
00462 Ptr<T> refU, refV, mbaU, mbaV, U, V;
00463 Ptr< Ptr< point<T> > > refP, tmp1P, P;
00464 Ptr< Ptr< point1<T> > > mbaPz, tmp2P;
00465 Ptr<T> tmp1U, tmp1V, tmp2U, tmp2V;
00466 int tmp1_nu, tmp1_nv, tmp2_nu, tmp2_nv;
00467 int tmp1_pu, tmp1_pv, tmp2_pu, tmp2_pv;
00468 T x,y,z,ox,oy,sint,cost,theta;
00469 Ptr< Ptr<HP> > Pw;
00470 point<T> CP;
00471
00472 mbaPoints.reserve_pool(nDatPoints);
00473
00474 if( minimize != 0 )
00475 {
00476
00477
00478 theta = MinimizeBBoxAboutZ( nDatPoints, datPoints, (T)1, 20 );
00479
00480 sint = rtr<T>::sin(theta);
00481 cost = rtr<T>::cos(theta);
00482
00483
00484 ox = datPoints[0].x;
00485 oy = datPoints[0].y;
00486 z = datPoints[0].z;
00487 minz = maxz = z;
00488 minx = maxx = x = cost * ox + sint * oy;
00489 miny = maxy = y = cost * oy - sint * ox;
00490 mbaPoints[0].x = x;
00491 mbaPoints[0].y = y;
00492 mbaPoints[0].z = z;
00493
00494
00495 for( i = 1; i < nDatPoints; i++ )
00496 {
00497 ox = datPoints[i].x;
00498 oy = datPoints[i].y;
00499 z = datPoints[i].z;
00500 x = cost * ox + sint * oy;
00501 y = cost * oy - sint * ox;
00502
00503 if( x < minx ) minx = x;
00504 else if( x > maxx ) maxx = x;
00505 if( y < miny ) miny = y;
00506 else if( y > maxy ) maxy = y;
00507 if( z < minz ) minz = z;
00508 else if( z > maxz ) maxz = z;
00509
00510 mbaPoints[i].x = x;
00511 mbaPoints[i].y = y;
00512 mbaPoints[i].z = z;
00513 }
00514
00515 for( i = 0; i < nDatPoints; i++ )
00516 {
00517 mbaPoints[i].x = (mbaPoints[i].x - minx) / (maxx-minx);
00518 if( mbaPoints[i].x < (T)0 ) mbaPoints[i].x = (T)0;
00519 else if( mbaPoints[i].x > (T)1 ) mbaPoints[i].x = (T)1;
00520 mbaPoints[i].y = (mbaPoints[i].y - miny) / (maxy-miny);
00521 if( mbaPoints[i].y < (T)0 ) mbaPoints[i].y = (T)0;
00522 else if( mbaPoints[i].y > (T)1 ) mbaPoints[i].y = (T)1;
00523 mbaPoints[i].z = (mbaPoints[i].z - minz) / (maxz-minz);
00524 }
00525 }
00526 else
00527 {
00528
00529
00530 CalcBoundingBoxE( nDatPoints, datPoints,
00531 minx, maxx, miny, maxy, minz, maxz );
00532
00533 for( i = 0; i < nDatPoints; i++ )
00534 {
00535 mbaPoints[i].x = (datPoints[i].x - minx) / (maxx-minx);
00536 if( mbaPoints[i].x < (T)0 ) mbaPoints[i].x = (T)0;
00537 else if( mbaPoints[i].x > (T)1 ) mbaPoints[i].x = (T)1;
00538 mbaPoints[i].y = (datPoints[i].y - miny) / (maxy-miny);
00539 if( mbaPoints[i].y < (T)0 ) mbaPoints[i].y = (T)0;
00540 else if( mbaPoints[i].y > (T)1 ) mbaPoints[i].y = (T)1;
00541 mbaPoints[i].z = (datPoints[i].z - minz) / (maxz-minz);
00542 }
00543 }
00544
00545
00546
00547 mba_nu = pu + (1<<(nIter-1)) - 1;
00548 mbaU.reserve_pool( 2*pu + (1<<(nIter-1)) + 1 );
00549 mba_nv = pv + (1<<(nIter-1)) - 1;
00550 mbaV.reserve_pool( 2*pv + (1<<(nIter-1)) + 1 );
00551 mbaPz.reserve_pool(mba_nv+1);
00552 Pw.reserve_pool(mba_nv+1);
00553 for( i = 0; i < mba_nv+1; i++ )
00554 {
00555 mbaPz[i].reserve_pool(mba_nu+1);
00556 Pw[i].reserve_pool(mba_nu+1);
00557 }
00558 MBAapproximate<T>( nDatPoints, mbaPoints, useStdDevs, StdDevs,
00559 nIter, pu, pv, mbaU, mbaV, mbaPz );
00560
00561
00562
00563
00564 refU.reserve_pool(4);
00565 for( i = 0; i < 2; i++ )
00566 {
00567 refU[i] = (T)0;
00568 refU[i+2] = (T)1;
00569 }
00570 refV = refU;
00571 ref_nu = 1;
00572 ref_pu = 1;
00573 ref_nv = 1;
00574 ref_pv = 1;
00575
00576 refP.reserve_pool(2);
00577 refP[0].reserve_pool(2);
00578 refP[1].reserve_pool(2);
00579
00580 refP[0][0].x = (T)0; refP[0][0].y = (T)0; refP[0][0].z = (T)0;
00581 refP[0][1].x = (T)1; refP[0][1].y = (T)0; refP[0][1].z = (T)0;
00582 refP[1][0].x = (T)0; refP[1][0].y = (T)1; refP[1][0].z = (T)0;
00583 refP[1][1].x = (T)1; refP[1][1].y = (T)1; refP[1][1].z = (T)0;
00584
00585
00586
00587 MakeSurfacesCompatible<T,point1<T>,point<T> >(
00588 mba_nu, pu, mbaU, mba_nv, pv, mbaV, mbaPz,
00589 ref_nu, ref_pu, refU, ref_nv, ref_pv, refV, refP,
00590 gul::v_direction,
00591 &tmp2_nu, &tmp2_pu, &tmp2U, &tmp2_nv, &tmp2_pv, &tmp2V, &tmp2P,
00592 &tmp1_nu, &tmp1_pu, &tmp1U, &tmp1_nv, &tmp1_pv, &tmp1V, &tmp1P );
00593
00594 MakeSurfacesCompatible<T,point1<T>,point<T> >(
00595 tmp2_nu, tmp2_pu, tmp2U, tmp2_nv, tmp2_pv, tmp2V, tmp2P,
00596 tmp1_nu, tmp1_pu, tmp1U, tmp1_nv, tmp1_pv, tmp1V, tmp1P,
00597 gul::u_direction,
00598 &mba_nu, &mba_pu, &mbaU, &mba_nv, &mba_pv, &mbaV, &mbaPz,
00599 &nu, &pu, &U, &nv, &pv, &V, &P );
00600
00601
00602
00603 for( j = 0; j <= nv; j++ )
00604 for( i = 0; i <= nu; i++ )
00605 P[j][i].z = mbaPz[j][i].x;
00606
00607
00608
00609 for( j = 0; j <= nv; j++ )
00610 for( i = 0; i <= nu; i++ )
00611 {
00612 CP.x = (P[j][i].x * (maxx-minx)) + minx;
00613 CP.y = (P[j][i].y * (maxy-miny)) + miny;
00614 CP.z = (P[j][i].z * (maxz-minz)) + minz;
00615 Pw[j][i] = CP;
00616 }
00617
00618 if( minimize != 0 )
00619 {
00620
00621
00622 sint = rtr<T>::sin(-theta);
00623 cost = rtr<T>::cos(-theta);
00624
00625 for( j = 0; j <= nv; j++ )
00626 for( i = 0; i <= nu; i++ )
00627 {
00628 ox = Pw[j][i].x;
00629 oy = Pw[j][i].y;
00630
00631 x = cost * ox + sint * oy;
00632 y = cost * oy - sint * ox;
00633
00634 Pw[j][i].x = x;
00635 Pw[j][i].y = y;
00636 }
00637 }
00638
00639
00640
00641 *ret_nu = nu;
00642 *retU = U;
00643 *ret_nv = nv;
00644 *retV = V;
00645 *retPw = Pw;
00646 }
00647 template GULAPI void SurfaceOverXYPlane(
00648 int nDatPoints, Ptr< point<float> >& datPoints,
00649 bool useStdDevs, Ptr<float>& StdDevs,
00650 bool minimize, int nIterations,
00651 int pu, int pv,
00652 int *ret_nu, Ptr<float> *retU,
00653 int *ret_nv, Ptr<float> *retV,
00654 Ptr< Ptr< point<float> > > *retPw );
00655 template GULAPI void SurfaceOverXYPlane(
00656 int nDatPoints, Ptr< point<double> >& datPoints,
00657 bool useStdDevs, Ptr<double>& StdDevs,
00658 bool minimize, int nIterations,
00659 int pu, int pv,
00660 int *ret_nu, Ptr<double> *retU,
00661 int *ret_nv, Ptr<double> *retV,
00662 Ptr< Ptr< point<double> > > *retPw );
00663
00664
00665
00666
00667
00668
00669
00670
00671 template< class T >
00672 void GULAPI MBASurface( int nDat, Ptr< point<T> > Dat, Ptr< point2<T> > Dom,
00673 int nIter, int pu, int pv,
00674 int *ret_nu, Ptr<T> *retU,
00675 int *ret_nv, Ptr<T> *retV,
00676 Ptr< Ptr< point<T> > > *retP )
00677 {
00678 T minu,maxu,minv,maxv;
00679 int nu,nv,i,j;
00680 Ptr<T> U,V,null;
00681 Ptr< Ptr< point1<T> > > F;
00682 Ptr< point<T> > coord;
00683 Ptr< Ptr< point<T> > > Pw;
00684
00685
00686
00687 coord.reserve_pool(nDat);
00688
00689 nu = pu + (1<<(nIter-1)) - 1;
00690 U.reserve_pool( 2*pu + (1<<(nIter-1)) + 1 );
00691 nv = pv + (1<<(nIter-1)) - 1;
00692 V.reserve_pool( 2*pv + (1<<(nIter-1)) + 1 );
00693 F.reserve_pool(nv+1);
00694 Pw.reserve_pool(nv+1);
00695 for( i = 0; i < nv+1; i++ )
00696 {
00697 F[i].reserve_pool(nu+1);
00698 Pw[i].reserve_pool(nu+1);
00699 }
00700
00701
00702
00703 CalcBoundingBoxE( nDat, Dom, minu, maxu, minv, maxv );
00704
00705 for( i = 0; i < nDat; i++ )
00706 {
00707 coord[i].x = (Dom[i].x - minu) / (maxu-minu);
00708 if( coord[i].x < (T)0 ) coord[i].x = (T)0;
00709 else if( coord[i].x > (T)1 ) coord[i].x = (T)1;
00710
00711 coord[i].y = (Dom[i].y - minv) / (maxv-minv);
00712 if( coord[i].y < (T)0 ) coord[i].y = (T)0;
00713 else if( coord[i].y > (T)1 ) coord[i].y = (T)1;
00714 }
00715
00716
00717
00718 for( i = 0; i < nDat; i++ )
00719 coord[i].z = Dat[i].x;
00720
00721 MBAapproximate<T>( nDat, coord, false, null,
00722 nIter, pu, pv, U, V, F );
00723
00724 for( i = 0; i <= nv; i++ )
00725 for( j = 0; j <= nu; j++ )
00726 Pw[i][j].x = F[i][j].x;
00727
00728
00729
00730 for( i = 0; i < nDat; i++ )
00731 coord[i].z = Dat[i].y;
00732
00733 MBAapproximate<T>( nDat, coord, false, null,
00734 nIter, pu, pv, U, V, F );
00735
00736 for( i = 0; i <= nv; i++ )
00737 for( j = 0; j <= nu; j++ )
00738 Pw[i][j].y = F[i][j].x;
00739
00740
00741
00742 for( i = 0; i < nDat; i++ )
00743 coord[i].z = Dat[i].z;
00744
00745 MBAapproximate<T>( nDat, coord, false, null,
00746 nIter, pu, pv, U, V, F );
00747
00748 for( i = 0; i <= nv; i++ )
00749 for( j = 0; j <= nu; j++ )
00750 Pw[i][j].z = F[i][j].x;
00751
00752
00753
00754 *ret_nu = nu;
00755 *retU = U;
00756 *ret_nv = nv;
00757 *retV = V;
00758 *retP = Pw;
00759 }
00760
00761
00762 template GULAPI void MBASurface(
00763 int nDat, const Ptr< point<float> > Dat, const Ptr< point2<float> > Dom,
00764 int nIter, int pu, int pv,
00765 int *ret_nu, Ptr<float> *retU,
00766 int *ret_nv, Ptr<float> *retV,
00767 Ptr< Ptr< point<float> > > *retP );
00768
00769 template GULAPI void MBASurface(
00770 int nDat, const Ptr< point<double> > Dat, const Ptr< point2<double> > Dom,
00771 int nIter, int pu, int pv,
00772 int *ret_nu, Ptr<double> *retU,
00773 int *ret_nv, Ptr<double> *retV,
00774 Ptr< Ptr< point<double> > > *retP );
00775
00776
00777
00778 }
00779
00780
00781