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 "gunu_parametrize.h"
00026 #include "guma_lineq.h"
00027 #include "gunu_basics.h"
00028 #include "gul_matrix.h"
00029 #include "gul_io.h"
00030
00031 namespace gunu {
00032
00033 using gul::Ptr;
00034 using gul::point;
00035 using gul::point1;
00036 using gul::point2;
00037 using guma::BandDecomposition;
00038 using guma::BandBackSubstitution;
00039 using gul::Min;
00040 using gul::Max;
00041 using gul::MMProduct;
00042 using gul::dump_matrix;
00043 using gul::dump_vector;
00044 using guma::LUDecomposition;
00045 using guma::LUBackSubstitution;
00046 using guma::SVDecomposition;
00047 using guma::SVZero;
00048 using guma::SVBackSubstitution;
00049 using gul::ndebug;
00050 using gul::Assert;
00051 using gul::InternalError;
00052
00053 using std::cout;
00054
00055 template< class T >
00056 void CASolve( int nQ, const Ptr< point<T> >& Q, const Ptr<T>& Uq,
00057 int n, int p, const Ptr<T>& U, Ptr<int>& M,
00058 Ptr< Ptr< Ptr<T> > >& N, Ptr< Ptr<T> >& A,
00059 Ptr< point<T> >& P )
00060 {
00061 int i,j,k,sign,offset,bw,shift;
00062 Ptr<T> Rx,Ry,Rz;
00063 Ptr< Ptr<T> > L;
00064 Ptr<int> index;
00065 point<T> r;
00066
00067 Rx.reserve_pool(n-1);
00068 Ry.reserve_pool(n-1);
00069 Rz.reserve_pool(n-1);
00070 for( i = 0; i < n-1; i++ )
00071 {
00072 Rx[i] = (T)0;
00073 Ry[i] = (T)0;
00074 Rz[i] = (T)0;
00075 }
00076
00077
00078
00079 for( i = 1; i < M[0]; i++ )
00080 {
00081 r = N[0][0][i] * Q[0];
00082 if( n-p == 0 )
00083 r = r + N[0][p][i]*Q[nQ-1];
00084
00085 for( j = 1; j <= Min(p,n-1); j++ )
00086 {
00087 Rx[j-1] += N[0][j][i] * (Q[i].x - r.x);
00088 Ry[j-1] += N[0][j][i] * (Q[i].y - r.y);
00089 Rz[j-1] += N[0][j][i] * (Q[i].z - r.z);
00090
00091
00092
00093
00094
00095 }
00096 }
00097
00098
00099
00100 offset = i;
00101 for( k = 1; k < n-p; k++ )
00102 {
00103 for( i = 0; i < M[k]; i++ )
00104 {
00105 for( j = 0; j <= p; j++ )
00106 {
00107 Rx[k+j-1] += N[k][j][i] * Q[offset+i].x;
00108 Ry[k+j-1] += N[k][j][i] * Q[offset+i].y;
00109 Rz[k+j-1] += N[k][j][i] * Q[offset+i].z;
00110
00111
00112
00113
00114
00115 }
00116 }
00117 offset += M[k];
00118 }
00119
00120
00121
00122 if( n-p > 0 )
00123 {
00124 for( i = 0; i < M[k]-1; i++ )
00125 {
00126 r = N[k][p][i] * Q[nQ-1];
00127
00128 for( j = 0; j < p; j++ )
00129 {
00130 Rx[k+j-1] += N[k][j][i] * (Q[offset+i].x - r.x);
00131 Ry[k+j-1] += N[k][j][i] * (Q[offset+i].y - r.y);
00132 Rz[k+j-1] += N[k][j][i] * (Q[offset+i].z - r.z);
00133
00134
00135
00136
00137
00138 }
00139 }
00140 }
00141 N.reset();
00142 M.reset();
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 L.reserve_pool(n-1);
00154 for( i = 0; i < n-1; i++ )
00155 L[i].reserve_pool(p);
00156 index.reserve_pool(n-1);
00157
00158 if( n-1 < p )
00159 {
00160 bw = n-1;
00161 shift = p - bw;
00162
00163 for( i = 0; i < n-1; i++ )
00164 {
00165 offset = bw-i;
00166 for( j = 0; j < bw+bw+1-offset; j++ )
00167 A[i][offset+j] = A[i][offset+j+shift];
00168 }
00169 }
00170 else
00171 bw = p;
00172
00173
00174
00175
00176
00177
00178 BandDecomposition( n-1, bw, bw, A, L, &sign, index );
00179
00180
00181
00182
00183
00184
00185
00186
00187 BandBackSubstitution( n-1, bw, bw, A, L, index, Rx );
00188 for( i = 0; i < n-1; i++ ) P[i+1].x = Rx[i];
00189 BandBackSubstitution( n-1, bw, bw, A, L, index, Ry );
00190 for( i = 0; i < n-1; i++ ) P[i+1].y = Ry[i];
00191 BandBackSubstitution( n-1, bw, bw, A, L, index, Rz );
00192 for( i = 0; i < n-1; i++ ) P[i+1].z = Rz[i];
00193
00194 P[0] = Q[0];
00195 P[n] = Q[nQ-1];
00196 }
00197
00198 template< class T >
00199 void CASolve( int nQ, const Ptr< point2<T> >& Q, const Ptr<T>& Uq,
00200 int n, int p, const Ptr<T>& U, Ptr<int>& M,
00201 Ptr< Ptr< Ptr<T> > >& N, Ptr< Ptr<T> >& A,
00202 Ptr< point2<T> >& P )
00203 {
00204 int i,j,k,sign,offset,bw,shift;
00205 Ptr<T> Rx,Ry,Rz;
00206 Ptr< Ptr<T> > L;
00207 Ptr<int> index;
00208 point2<T> r;
00209
00210 Rx.reserve_pool(n-1);
00211 Ry.reserve_pool(n-1);
00212 for( i = 0; i < n-1; i++ )
00213 {
00214 Rx[i] = (T)0;
00215 Ry[i] = (T)0;
00216 }
00217
00218
00219 for( i = 1; i < M[0]; i++ )
00220 {
00221 r = N[0][0][i] * Q[0];
00222 if( n-p == 0 )
00223 r = r + N[0][p][i]*Q[nQ-1];
00224
00225 for( j = 1; j <= Min(p,n-1); j++ )
00226 {
00227 Rx[j-1] += N[0][j][i] * (Q[i].x - r.x);
00228 Ry[j-1] += N[0][j][i] * (Q[i].y - r.y);
00229 }
00230 }
00231
00232
00233
00234 offset = i;
00235 for( k = 1; k < n-p; k++ )
00236 {
00237 for( i = 0; i < M[k]; i++ )
00238 {
00239 for( j = 0; j <= p; j++ )
00240 {
00241 Rx[k+j-1] += N[k][j][i] * Q[offset+i].x;
00242 Ry[k+j-1] += N[k][j][i] * Q[offset+i].y;
00243 }
00244 }
00245 offset += M[k];
00246 }
00247
00248
00249
00250 if( n-p > 0 )
00251 {
00252 for( i = 0; i < M[k]-1; i++ )
00253 {
00254 r = N[k][p][i] * Q[nQ-1];
00255
00256 for( j = 0; j < p; j++ )
00257 {
00258 Rx[k+j-1] += N[k][j][i] * (Q[offset+i].x - r.x);
00259 Ry[k+j-1] += N[k][j][i] * (Q[offset+i].y - r.y);
00260 }
00261 }
00262 }
00263 N.reset();
00264 M.reset();
00265
00266 L.reserve_pool(n-1);
00267 for( i = 0; i < n-1; i++ )
00268 L[i].reserve_pool(p+p+1);
00269 index.reserve_pool(n-1);
00270
00271 if( n-1 < p )
00272 {
00273 bw = n-1;
00274 shift = p - bw;
00275
00276 for( i = 0; i < n-1; i++ )
00277 {
00278 offset = bw-i;
00279 for( j = 0; j < bw+bw+1-offset; j++ )
00280 A[i][offset+j] = A[i][offset+j+shift];
00281 }
00282 }
00283 else
00284 bw = p;
00285
00286 BandDecomposition( n-1, bw, bw, A, L, &sign, index );
00287
00288 BandBackSubstitution( n-1, bw, bw, A, L, index, Rx );
00289 for( i = 0; i < n-1; i++ ) P[i+1].x = Rx[i];
00290 BandBackSubstitution( n-1, bw, bw, A, L, index, Ry );
00291 for( i = 0; i < n-1; i++ ) P[i+1].y = Ry[i];
00292
00293 P[0] = Q[0];
00294 P[n] = Q[nQ-1];
00295 }
00296
00297 template< class T >
00298 void CASolveToCol(
00299 int nQ, const Ptr< point<T> >& Q, const Ptr<T>& Uq,
00300 int n, int p, const Ptr<T>& U, const Ptr<int>& M,
00301 const Ptr< Ptr< Ptr<T> > >& N, Ptr< Ptr<T> >& A,
00302 Ptr< Ptr<T> >& L, Ptr<int> index,
00303 int iCol, Ptr< Ptr< point<T> > >& P )
00304 {
00305 int i,j,k,offset;
00306 Ptr<T> Rx,Ry,Rz;
00307 point<T> r;
00308
00309 Rx.reserve_pool(n-1);
00310 Ry.reserve_pool(n-1);
00311 Rz.reserve_pool(n-1);
00312 for( i = 0; i < n-1; i++ )
00313 {
00314 Rx[i] = (T)0;
00315 Ry[i] = (T)0;
00316 Rz[i] = (T)0;
00317 }
00318
00319
00320
00321 for( i = 1; i < M[0]; i++ )
00322 {
00323 r = N[0][0][i] * Q[0];
00324 if( n-p == 0 )
00325 r = r + N[0][p][i]*Q[nQ-1];
00326
00327 for( j = 1; j <= Min(p,n-1); j++ )
00328 {
00329 Rx[j-1] += N[0][j][i] * (Q[i].x - r.x);
00330 Ry[j-1] += N[0][j][i] * (Q[i].y - r.y);
00331 Rz[j-1] += N[0][j][i] * (Q[i].z - r.z);
00332 }
00333 }
00334
00335
00336
00337 offset = i;
00338 for( k = 1; k < n-p; k++ )
00339 {
00340 for( i = 0; i < M[k]; i++ )
00341 {
00342 for( j = 0; j <= p; j++ )
00343 {
00344 Rx[k+j-1] += N[k][j][i] * Q[offset+i].x;
00345 Ry[k+j-1] += N[k][j][i] * Q[offset+i].y;
00346 Rz[k+j-1] += N[k][j][i] * Q[offset+i].z;
00347 }
00348 }
00349 offset += M[k];
00350 }
00351
00352
00353
00354 if( n-p > 0 )
00355 {
00356 for( i = 0; i < M[k]-1; i++ )
00357 {
00358 r = N[k][p][i] * Q[nQ-1];
00359
00360 for( j = 0; j < p; j++ )
00361 {
00362 Rx[k+j-1] += N[k][j][i] * (Q[offset+i].x - r.x);
00363 Ry[k+j-1] += N[k][j][i] * (Q[offset+i].y - r.y);
00364 Rz[k+j-1] += N[k][j][i] * (Q[offset+i].z - r.z);
00365 }
00366 }
00367 }
00368
00369
00370 BandBackSubstitution( n-1, Min(p,n-1), Min(p,n-1), A, L, index, Rx );
00371 for( i = 0; i < n-1; i++ ) P[i+1][iCol].x = Rx[i];
00372 BandBackSubstitution( n-1, Min(p,n-1), Min(p,n-1), A, L, index, Ry );
00373 for( i = 0; i < n-1; i++ ) P[i+1][iCol].y = Ry[i];
00374 BandBackSubstitution( n-1, Min(p,n-1), Min(p,n-1), A, L, index, Rz );
00375 for( i = 0; i < n-1; i++ ) P[i+1][iCol].z = Rz[i];
00376
00377 P[0][iCol] = Q[0];
00378 P[n][iCol] = Q[nQ-1];
00379 }
00380
00381 template< class T >
00382 void CACalcNTN( int nQ, const Ptr<T>& Uq,
00383 int n, int p, const Ptr<T>& U, Ptr<int>& M,
00384 Ptr< Ptr< Ptr<T> > >& N, Ptr< Ptr<T> >& A )
00385 {
00386 Ptr<T> B;
00387 T u,sum;
00388 int offset,span,i,j,k,l,m;
00389
00390 B.reserve_pool(p+1);
00391
00392 span = p;
00393 offset = 0;
00394
00395 for( i = 0; i < nQ; i++ )
00396 {
00397 u = Uq[i];
00398
00399 while( (u >= U[span+1]) && (span != n) )
00400 {
00401 M[span-p] = i - offset;
00402 span++;
00403 offset = i;
00404 }
00405 CalcBasisFunctions( u, span, p, U, B );
00406
00407 for( j = 0; j <= p; j++ )
00408 N[span-p][j][i-offset] = B[j];
00409 }
00410 M[n-p] = nQ - offset;
00411
00412
00413
00414
00415
00416
00417
00418 for( i = 1; i < n; i++ )
00419 {
00420 m = i-p;
00421
00422 for( j = Max(0,-m); j <= p; j++ )
00423 {
00424 sum = (T)0;
00425 for( k = Min(j,n-i); k >= Max(0,-m); k-- )
00426 {
00427 for( l = 0; l < M[m+k]; l++ )
00428 sum += N[m+k][p-k][l]*N[m+k][j-k][l];
00429 }
00430 A[i-1][j] = sum;
00431 }
00432 for( j = Max(0,i+p-n); j < p; j++ )
00433 {
00434 sum = (T)0;
00435 for( k = Max(0,i+p-n); k <= Min(j,i); k++ )
00436 {
00437 for( l = 0; l < M[i-k]; l++ )
00438 sum += N[i-k][k][l]*N[i-k][p-j+k][l];
00439 }
00440 A[i-1][p+p-j] = sum;
00441 }
00442 }
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452 template< class T, class EP >
00453 GULAPI bool DoGlobalCurveApproximation(
00454 int nQ,
00455 const Ptr<EP>& Q, const
00456 Ptr<T>& QU,
00457 int n,
00458 int p,
00459 const Ptr<T>& U,
00460 int max_pts_span,
00461 Ptr<EP>& P )
00462 {
00463 Ptr< Ptr< Ptr<T> > > N;
00464 int i,j;
00465 Ptr< Ptr<T> > A;
00466 Ptr<int> M;
00467
00468 if( p < 2 ) return false;
00469 if( n < p ) return false;
00470 if( nQ <= n+1 ) return false;
00471
00472 M.reserve_pool(n-p+1);
00473 N.reserve_pool(n-p+1);
00474 for( i = 0; i <= n-p; i++ ) {
00475 N[i].reserve_pool(p+1);
00476 for( j = 0; j <= p; j++ ) N[i][j].reserve_pool(max_pts_span);
00477 }
00478 A.reserve_pool(n-1);
00479 for( i = 0; i < n-1; i++ )
00480 A[i].reserve_pool(p+p+1);
00481
00482 CACalcNTN<T>( nQ, QU, n, p, U, M, N, A );
00483
00484
00485
00486
00487 CASolve( nQ, Q, QU, n, p, U, M, N, A, P );
00488
00489 return true;
00490 }
00491
00492 template GULAPI bool DoGlobalCurveApproximation(
00493 int nQ,
00494 const Ptr< point<float> >& Q, const
00495 Ptr<float>& QU,
00496 int n,
00497 int p,
00498 const Ptr<float>& U,
00499 int max_pts_span,
00500 Ptr< point<float> >& P );
00501 template GULAPI bool DoGlobalCurveApproximation(
00502 int nQ,
00503 const Ptr< point<double> >& Q, const
00504 Ptr<double>& QU,
00505 int n,
00506 int p,
00507 const Ptr<double>& U,
00508 int max_pts_span,
00509 Ptr< point<double> >& P );
00510 template GULAPI bool DoGlobalCurveApproximation(
00511 int nQ,
00512 const Ptr< point2<float> >& Q, const
00513 Ptr<float>& QU,
00514 int n,
00515 int p,
00516 const Ptr<float>& U,
00517 int max_pts_span,
00518 Ptr< point2<float> >& P );
00519 template GULAPI bool DoGlobalCurveApproximation(
00520 int nQ,
00521 const Ptr< point2<double> >& Q, const
00522 Ptr<double>& QU,
00523 int n,
00524 int p,
00525 const Ptr<double>& U,
00526 int max_pts_span,
00527 Ptr< point2<double> >& P );
00528
00529
00530
00531
00532
00533 template< class T, class EP >
00534 GULAPI bool GlobalCurveApproximation(int nQ, const Ptr<EP>& Q,
00535 int n, int p, Ptr<T>& U, Ptr<EP>& P )
00536 {
00537 Ptr<T> Uq,d;
00538 T sum;
00539 Ptr< Ptr< Ptr<T> > > N;
00540 int Mmax;
00541 Ptr< Ptr<T> > A;
00542 Ptr<int> M;
00543
00544
00545
00546 d.reserve_pool(nQ);
00547 Uq.reserve_pool(nQ);
00548
00549 sum = ChordLength( nQ, Q, d );
00550 if( sum == (T)0 ) return false;
00551 ChordLengthParameters( nQ, sum, d, Uq );
00552 if( !(Mmax = KnotVectorByAveraging(nQ, Uq, n, p, U)) ) return false;
00553
00554
00555
00556
00557
00558
00559
00560
00561 return DoGlobalCurveApproximation(nQ,Q,Uq,n,p,U,Mmax,P);
00562 }
00563
00564 template GULAPI bool GlobalCurveApproximation(
00565 int nQ, const Ptr< point<float> >& Q,
00566 int n, int p, Ptr<float>& U, Ptr< point<float> >& P );
00567 template GULAPI bool GlobalCurveApproximation(
00568 int nQ, const Ptr< point<double> >& Q,
00569 int n, int p, Ptr<double>& U, Ptr< point<double> >& P );
00570 template GULAPI bool GlobalCurveApproximation(
00571 int nQ, const Ptr< point2<float> >& Q,
00572 int n, int p, Ptr<float>& U, Ptr< point2<float> >& P );
00573 template GULAPI bool GlobalCurveApproximation(
00574 int nQ, const Ptr< point2<double> >& Q,
00575 int n, int p, Ptr<double>& U, Ptr< point2<double> >& P );
00576
00577
00578
00579
00580
00581 template< class T, class EP >
00582 GULAPI bool GlobalSurfaceApproximation(
00583 int nRows, int nCols, const Ptr< Ptr<EP> >& Q,
00584 int nu, int pu, Ptr<T>& U, int nv, int pv, Ptr<T>& V,
00585 Ptr< Ptr<EP> > &P )
00586 {
00587 Ptr<T> Uq,Vq;
00588 Ptr< Ptr< Ptr<T> > > N;
00589 int i,j,Mmaxu,Mmaxv,sign,offset,bw,shift;
00590 Ptr< Ptr<T> > A,L;
00591 Ptr< Ptr<EP> > R;
00592 Ptr<int> index,M;
00593
00594 if( (pu < 2) || (pv < 2) ) return false;
00595 if( (nu < pu) || (nv < pv) ) return false;
00596 if( (nRows <= nv+1) || (nCols <= nu+1) ) return false;
00597
00598 Uq.reserve_pool(nCols);
00599 Vq.reserve_pool(nRows);
00600
00601 if( !ChordLengthMeshParams( nRows, nCols, Q, Uq, Vq ) ) return false;
00602
00603 if( !(Mmaxu = KnotVectorByAveraging(nCols, Uq, nu, pu, U)) ) return false;
00604 if( !(Mmaxv = KnotVectorByAveraging(nRows, Vq, nv, pv, V)) ) return false;
00605
00606
00607
00608 M.reserve_pool(nu-pu+1);
00609 N.reserve_pool(nu-pu+1);
00610 for( i = 0; i <= nu-pu; i++ ) {
00611 N[i].reserve_pool(pu+1);
00612 for( j = 0; j <= pu; j++ ) N[i][j].reserve_pool(Mmaxu);
00613 }
00614 A.reserve_pool(nu-1);
00615 for( i = 0; i < nu-1; i++ )
00616 A[i].reserve_pool(pu+pu+1);
00617
00618 R.reserve_pool(nu+1);
00619 for( i = 0; i <= nu; i++ )
00620 R[i].reserve_pool(nRows);
00621
00622 CACalcNTN<T>( nCols, Uq, nu, pu, U, M, N, A );
00623
00624 L.reserve_pool(nu-1);
00625 for( i = 0; i < nu-1; i++ )
00626 L[i].reserve_pool(pu+pu+1);
00627 index.reserve_pool(nu-1);
00628
00629 if( nu-1 < pu )
00630 {
00631 bw = nu-1;
00632 shift = pu - bw;
00633
00634 for( i = 0; i < nu-1; i++ )
00635 {
00636 offset = bw-i;
00637 for( j = 0; j < bw+bw+1-offset; j++ )
00638 A[i][offset+j] = A[i][offset+j+shift];
00639 }
00640 }
00641 else
00642 bw = pu;
00643
00644 BandDecomposition( nu-1, bw, bw, A, L, &sign, index );
00645
00646 for( i = 0; i < nRows; i++ )
00647 {
00648 CASolveToCol( nCols, Q[i], Uq, nu, pu, U, M, N, A, L, index, i, R );
00649 }
00650
00651
00652
00653 M.reserve_pool(nv-pv+1);
00654 N.reserve_pool(nv-pv+1);
00655 for( i = 0; i <= nv-pv; i++ ) {
00656 N[i].reserve_pool(pv+1);
00657 for( j = 0; j <= pv; j++ ) N[i][j].reserve_pool(Mmaxv);
00658 }
00659 A.reserve_pool(nv-1);
00660 for( i = 0; i < nv-1; i++ )
00661 A[i].reserve_pool(pv+pv+1);
00662
00663 CACalcNTN<T>( nRows, Vq, nv, pv, V, M, N, A );
00664
00665 L.reserve_pool(nv-1);
00666 for( i = 0; i < nv-1; i++ )
00667 L[i].reserve_pool(pv+pv+1);
00668 index.reserve_pool(nv-1);
00669
00670 if( nv-1 < pv )
00671 {
00672 bw = nv-1;
00673 shift = pv - bw;
00674
00675 for( i = 0; i < nv-1; i++ )
00676 {
00677 offset = bw-i;
00678 for( j = 0; j < bw+bw+1-offset; j++ )
00679 A[i][offset+j] = A[i][offset+j+shift];
00680 }
00681 }
00682 else
00683 bw = pv;
00684
00685 BandDecomposition( nv-1, bw, bw, A, L, &sign, index );
00686
00687 for( i = 0; i <= nu; i++ )
00688 {
00689 CASolveToCol( nRows, R[i], Vq, nv, pv, V, M, N, A, L, index, i, P );
00690 }
00691
00692 return true;
00693 }
00694
00695 template GULAPI bool GlobalSurfaceApproximation< float,point<float> >(
00696 int nRows, int nCols, const Ptr< Ptr< point<float> > >& Q,
00697 int pu, int nu, Ptr<float>& U, int nv, int pv, Ptr<float>& V,
00698 Ptr< Ptr< point<float> > >& P );
00699 template GULAPI bool GlobalSurfaceApproximation< double,point<double> >(
00700 int nRows, int nCols, const Ptr< Ptr< point<double> > >& Q,
00701 int pu, int nu, Ptr<double>& U, int nv, int pv, Ptr<double>& V,
00702 Ptr< Ptr< point<double> > >& P );
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 #if 0
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 template< class T >
00729 bool GlobalCurveApproximationDBG(int nQ, const Ptr< point<T> >& Q,
00730 int n, int p, Ptr<T>& U, Ptr< point<T> >& P )
00731 {
00732 Ptr<T> Uq,d,B,rx,ry,rz,Rx,Ry,Rz;
00733 T sum,u;
00734 int i,j,Mmax,span,sign;
00735 Ptr< Ptr<T> > N,NT,NTN,A;
00736 Ptr<int> index;
00737
00738 d.reserve_pool(nQ);
00739 Uq.reserve_pool(nQ);
00740
00741 sum = ChordLength( nQ, Q, d );
00742 if( sum == (T)0 ) return false;
00743 ChordLengthParameters( nQ, sum, d, Uq );
00744 if( !(Mmax = KnotVectorByAveraging(nQ, Uq, n, p, U)) ) return false;
00745
00746
00747
00748
00749
00750
00751
00752
00753 N.reserve_pool(nQ);
00754 for( i = 0; i < nQ; i++ )
00755 N[i].reserve_pool(n+1);
00756
00757 span = p;
00758 for( i = 0; i < nQ; i++ )
00759 {
00760 u = Uq[i];
00761
00762 if( (u >= U[span+1]) && (span != n) ) span++;
00763
00764 B.use_pointer(&N[i][span-p],p+1);
00765 CalcBasisFunctions( u, span, p, U, B );
00766
00767 for( j = 0; j < span-p; j++ ) N[i][j] = (T)0;
00768 for( j = span+1; j <= n; j++ ) N[i][j] = (T)0;
00769 }
00770
00771
00772
00773
00774
00775
00776 NT.reserve_pool(n+1);
00777 for( i = 0; i <= n; i++ )
00778 NT[i].reserve_pool(nQ);
00779
00780 for( i = 0; i <= n; i++ )
00781 for( j = 0; j < nQ; j++ )
00782 NT[i][j] = N[j][i];
00783
00784 NTN.reserve_pool(n+1);
00785 for( i = 0; i <= n; i++ )
00786 NTN[i].reserve_pool(n+1);
00787
00788 MMProduct( n+1, nQ, n+1, NT, N, NTN );
00789
00790
00791
00792
00793
00794
00795 rx.reserve_pool(nQ);
00796 ry.reserve_pool(nQ);
00797 rz.reserve_pool(nQ);
00798
00799 for( i = 1; i < nQ-1; i++ )
00800 {
00801 rx[i] = Q[i].x - N[i][0]*Q[0].x - N[i][n]*Q[nQ-1].x;
00802 ry[i] = Q[i].y - N[i][0]*Q[0].y - N[i][n]*Q[nQ-1].y;
00803 rz[i] = Q[i].z - N[i][0]*Q[0].z - N[i][n]*Q[nQ-1].z;
00804 }
00805
00806 Rx.reserve_pool(n-1);
00807 Ry.reserve_pool(n-1);
00808 Rz.reserve_pool(n-1);
00809
00810 for( i = 1; i < n; i++ )
00811 {
00812 Rx[i-1] = (T)0;
00813 Ry[i-1] = (T)0;
00814 Rz[i-1] = (T)0;
00815 for( j = 1; j < nQ-1; j++ )
00816 {
00817 Rx[i-1] += N[j][i]*rx[j];
00818 Ry[i-1] += N[j][i]*ry[j];
00819 Rz[i-1] += N[j][i]*rz[j];
00820
00821
00822
00823
00824
00825 }
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 A.reserve_pool(n-1);
00838 for( i = 0; i < n-1; i++ ) A[i].reserve_pool(n-1);
00839 index.reserve_pool(n-1);
00840
00841 for( i = 0; i < n-1; i++ )
00842 for( j = 0; j < n-1; j++ )
00843 A[i][j] = NTN[i+1][j+1];
00844
00845
00846 cout << "solving with SVD\n";
00847
00848 Ptr< Ptr<T> > SV;
00849 Ptr<T> Sw;
00850
00851 SV.reserve_pool(n-1);
00852 for( i = 0; i < n-1; i++ ) SV[i].reserve_pool(n-1);
00853 Sw.reserve_pool(n-1);
00854
00855 SVDecomposition( n-1, n-1, A, Sw, SV );
00856
00857 bool illcond = !SVZero( n-1, Sw );
00858 if( illcond ) cout << "Coefficients matrix ill conditioned!\n";
00859
00860 SVBackSubstitution( n-1, n-1, A, Sw, SV, Rx );
00861 SVBackSubstitution( n-1, n-1, A, Sw, SV, Ry );
00862 SVBackSubstitution( n-1, n-1, A, Sw, SV, Rz );
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 for( i = 1; i <= n-1; i++ )
00875 {
00876 P[i].x = Rx[i-1];
00877 P[i].y = Ry[i-1];
00878 P[i].z = Rz[i-1];
00879 }
00880 P[0] = Q[0];
00881 P[n] = Q[nQ-1];
00882
00883 return true;
00884 }
00885
00886 template bool GlobalCurveApproximationDBG(
00887 int nQ, const Ptr< point<float> >& Q,
00888 int n, int p, Ptr<float>& U, Ptr< point<float> >& P );
00889 template bool GlobalCurveApproximationDBG(
00890 int nQ, const Ptr< point<double> >& Q,
00891 int n, int p, Ptr<double>& U, Ptr< point<double> >& P );
00892
00893
00894 template< class T >
00895 bool GlobalCurveApproximationDBG(int nQ, const Ptr< point2<T> >& Q,
00896 int n, int p, Ptr<T>& U, Ptr< point2<T> >& P )
00897 {
00898 Ptr<T> Uq,d,B,rx,ry,rz,Rx,Ry,Rz;
00899 T sum,u;
00900 int i,j,Mmax,span,sign;
00901 Ptr< Ptr<T> > N,NT,NTN,A;
00902 Ptr<int> index;
00903
00904 d.reserve_pool(nQ);
00905 Uq.reserve_pool(nQ);
00906
00907 sum = ChordLength( nQ, Q, d );
00908 if( sum == (T)0 ) return false;
00909 ChordLengthParameters( nQ, sum, d, Uq );
00910 if( !(Mmax = KnotVectorByAveraging(nQ, Uq, n, p, U)) ) return false;
00911
00912 N.reserve_pool(nQ);
00913 for( i = 0; i < nQ; i++ )
00914 N[i].reserve_pool(n+1);
00915
00916 span = p;
00917 for( i = 0; i < nQ; i++ )
00918 {
00919 u = Uq[i];
00920
00921 if( (u >= U[span+1]) && (span != n) ) span++;
00922
00923 B.use_pointer(&N[i][span-p],p+1);
00924 CalcBasisFunctions( u, span, p, U, B );
00925
00926 for( j = 0; j < span-p; j++ ) N[i][j] = (T)0;
00927 for( j = span+1; j <= n; j++ ) N[i][j] = (T)0;
00928 }
00929
00930
00931
00932
00933
00934
00935 NT.reserve_pool(n+1);
00936 for( i = 0; i <= n; i++ )
00937 NT[i].reserve_pool(nQ);
00938
00939 for( i = 0; i <= n; i++ )
00940 for( j = 0; j < nQ; j++ )
00941 NT[i][j] = N[j][i];
00942
00943 NTN.reserve_pool(n+1);
00944 for( i = 0; i <= n; i++ )
00945 NTN[i].reserve_pool(n+1);
00946
00947 MMProduct( n+1, nQ, n+1, NT, N, NTN );
00948
00949
00950
00951
00952
00953
00954 rx.reserve_pool(nQ);
00955 ry.reserve_pool(nQ);
00956 rz.reserve_pool(nQ);
00957
00958 for( i = 1; i < nQ-1; i++ )
00959 {
00960 rx[i] = Q[i].x - N[i][0]*Q[0].x - N[i][n]*Q[nQ-1].x;
00961 ry[i] = Q[i].y - N[i][0]*Q[0].y - N[i][n]*Q[nQ-1].y;
00962 }
00963
00964 Rx.reserve_pool(n-1);
00965 Ry.reserve_pool(n-1);
00966
00967 for( i = 1; i < n; i++ )
00968 {
00969 Rx[i-1] = (T)0;
00970 Ry[i-1] = (T)0;
00971 for( j = 1; j < nQ-1; j++ )
00972 {
00973 Rx[i-1] += N[j][i]*rx[j];
00974 Ry[i-1] += N[j][i]*ry[j];
00975 }
00976 }
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 A.reserve_pool(n-1);
00987 for( i = 0; i < n-1; i++ ) A[i].reserve_pool(n-1);
00988 index.reserve_pool(n-1);
00989
00990 for( i = 0; i < n-1; i++ )
00991 for( j = 0; j < n-1; j++ )
00992 A[i][j] = NTN[i+1][j+1];
00993
00994
00995
00996
00997 Ptr< Ptr<T> > SV;
00998 Ptr<T> Sw;
00999
01000 SV.reserve_pool(n-1);
01001 for( i = 0; i < n-1; i++ ) SV[i].reserve_pool(n-1);
01002 Sw.reserve_pool(n-1);
01003
01004 SVDecomposition( n-1, n-1, A, Sw, SV );
01005
01006 bool illcond = !SVZero( n-1, Sw );
01007 if( illcond ) cout << "Coefficients matrix ill conditioned!\n";
01008
01009 SVBackSubstitution( n-1, n-1, A, Sw, SV, Rx );
01010 SVBackSubstitution( n-1, n-1, A, Sw, SV, Ry );
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 for( i = 1; i <= n-1; i++ )
01023 {
01024 P[i].x = Rx[i-1];
01025 P[i].y = Ry[i-1];
01026 }
01027 P[0] = Q[0];
01028 P[n] = Q[nQ-1];
01029
01030 return true;
01031 }
01032 template bool GlobalCurveApproximationDBG(
01033 int nQ, const Ptr< point2<float> >& Q,
01034 int n, int p, Ptr<float>& U, Ptr< point2<float> >& P );
01035 template bool GlobalCurveApproximationDBG(
01036 int nQ, const Ptr< point2<double> >& Q,
01037 int n, int p, Ptr<double>& U, Ptr< point2<double> >& P );
01038 #endif
01039
01040 }
01041
01042
01043