00001 #include "rgrl_spline.h"
00002
00003
00004
00005
00006
00007 #include <vcl_cmath.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_cassert.h>
00010 #include <vnl/vnl_math.h>
00011 #include <vcl_vector.h>
00012
00013 static double g( int a1, int a2, int m );
00014 static double g_prime( int a1, int a2, int m );
00015 static double g_double_prime( int a1, int a2, int m );
00016
00017
00018
00019
00020
00021
00022
00023 static double bspline_basis_function( int i, double u );
00024 static double bspline_basis_prime_function( int i, double u );
00025
00026 rgrl_spline::
00027 rgrl_spline( vnl_vector< unsigned > const& m )
00028 : m_( m )
00029 {
00030 int n = 1;
00031 for (unsigned i=0; i<m.size(); ++i)
00032 n *= (m_[i]+3);
00033 c_.set_size(n);
00034 c_.fill( 0.0 );
00035 }
00036
00037 rgrl_spline::
00038 rgrl_spline( vnl_vector< unsigned > const& m, vnl_vector< double > const& c )
00039 : m_( m ), c_( c )
00040 {
00041 unsigned int n = 1;
00042 for (unsigned i=0; i<m.size(); ++i)
00043 n *= (m_[i]+3);
00044 assert ( c.size() == n );
00045 }
00046
00047 void
00048 rgrl_spline::
00049 set_control_points( vnl_vector<double> const& c )
00050 {
00051 unsigned n = 1;
00052 for (unsigned i=0; i < m_.size(); ++i)
00053 n *= (m_[i]+3);
00054 assert ( c.size() == n );
00055 c_ = c;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064 double
00065 rgrl_spline::
00066 f_x( vnl_vector<double> const& point ) const
00067 {
00068 assert ( point.size() == m_.size() );
00069
00070 for ( unsigned i=0; i<m_.size(); ++i ) {
00071
00072
00073 if ( point[i] < 0 || point[i] > m_[i] )
00074
00075
00076 return 0;
00077 }
00078
00079
00080
00081 static vnl_vector< double > gr;
00082 basis_response( point, gr );
00083
00084 return inner_product( c_, gr );
00085 }
00086
00087
00088 vnl_vector< double >
00089 rgrl_spline::
00090 jacobian( vnl_vector< double > const& point ) const
00091 {
00092 assert ( point.size() == m_.size() );
00093
00094
00095 for ( unsigned i=0; i<m_.size(); ++i ) {
00096
00097 if ( point[i] < 0 || point[i] > m_[i] )
00098 return vnl_vector< double >(m_.size(), 0.0);
00099 }
00100
00101 unsigned num_control_pts = 1;
00102 const unsigned dim = m_.size();
00103 for (unsigned n=0; n<dim; ++n)
00104 num_control_pts *= m_[n]+3;
00105
00106 vnl_matrix<double> br( dim, num_control_pts, 0 );
00107
00108 vnl_vector< int > floor( dim );
00109 vnl_vector< int > ceil( dim );
00110 vnl_vector< double > u( dim );
00111 vnl_vector< int > min( dim );
00112 vnl_vector< int > max( dim );
00113
00114 for ( unsigned n=0; n<dim; ++n ) {
00115 floor[n] = (int)vcl_floor( point[n] ) ;
00116 ceil[n] = (int)vcl_ceil( point[n] );
00117 u[n] = point[n] - floor[n];
00118 min[ n ] = ( floor[n] < 0 ) ? 0 : floor[n];
00119 max[ n ] = ( ceil[n] > (int)m_[n] ) ? m_[n] + 2 : ceil[n]+2;
00120 }
00121
00122
00123 if (dim == 3) {
00124 int a = (m_[0]+3) * (m_[1]+3);
00125 int b = m_[0]+3;
00126 for ( int i=min[2], index = a*i; i<=max[2]; ++i, index+=a ) {
00127 double b1 = bspline_basis_function( i-floor[2], u[2] );
00128 double b1_prime = bspline_basis_prime_function( i-floor[2], u[2] );
00129 for ( int j=min[1], d = b*j + index; j<=max[1]; ++j, d+=b ) {
00130 double b2 = bspline_basis_function( j-floor[1], u[1] );
00131 double b2_prime = bspline_basis_prime_function( j-floor[1], u[1] );
00132 for ( int k=min[0], e = d+k; k<=max[0]; ++k, ++e ) {
00133 double b3 = bspline_basis_function( k-floor[0], u[0] );
00134 double b3_prime = bspline_basis_prime_function( k-floor[0], u[0] );
00135 br(0, e) = b1_prime * b2 * b3;
00136 br(1, e) = b1 * b2_prime * b3;
00137
00138
00139 br(2, e) = b1 * b2 * b3_prime;
00140 }
00141 }
00142 }
00143 }
00144
00145 else if (dim == 2) {
00146 int a =(m_[0]+3);
00147 for ( int i=min[1], index = a*i; i<=max[1]; ++i, index+=a ) {
00148 double b1 = bspline_basis_function( i-floor[1], u[1] );
00149 double b1_prime = bspline_basis_prime_function( i-floor[1], u[1] );
00150 for ( int j=min[0], b = j + index; j<=max[0]; ++j, ++b ) {
00151 double b2 = bspline_basis_function( j-floor[0], u[0] );
00152 double b2_prime = bspline_basis_prime_function( j-floor[0], u[0] );
00153 br(0, b) = b1_prime * b2;
00154 br(1, b) = b1 * b2_prime;
00155 }
00156 }
00157 }
00158
00159 else if (dim == 1) {
00160 for ( int i=min[0], b = i; i<= max[0]; ++i, ++b ) {
00161 double b1_prime = bspline_basis_prime_function( i-floor[0], u[0] );
00162 br( 0, b ) = b1_prime;
00163 }
00164 }
00165 else
00166 assert ( !"dim should be 1, 2 or 3" );
00167
00168
00169
00170
00171
00172
00173 return br * c_;
00174 }
00175
00176 void
00177 rgrl_spline::
00178 basis_response( vnl_vector<double> const& point, vnl_vector<double>& br ) const
00179 {
00180 basis_response_helper( point, br, &bspline_basis_function );
00181 }
00182
00183 void
00184 rgrl_spline::
00185 basis_response_helper( vnl_vector<double> const& point, vnl_vector<double>& br, func_type basis_func ) const
00186 {
00187 unsigned num_element = 1;
00188 const unsigned dim = m_.size();
00189 for (unsigned n=0; n<dim; ++n)
00190 num_element *= m_[n]+3;
00191
00192 br.set_size(num_element);
00193 br.fill(0);
00194
00195 vnl_vector< int > floor(dim);
00196 vnl_vector< int > ceil(dim);
00197 vnl_vector< double > u(dim);
00198 vnl_vector< int > min( dim );
00199 vnl_vector< int > max( dim );
00200
00201 for ( unsigned n=0; n<dim; ++n ) {
00202 floor[n] = (int)vcl_floor( point[n] ) ;
00203 ceil[n] = (int)vcl_ceil( point[n] );
00204 u[n] = point[n] - floor[n];
00205 min[ n ] = ( floor[n] < 0 ) ? 0 : floor[n];
00206 max[ n ] = ( ceil[n] > (int)m_[n] ) ? m_[n] + 2 : ceil[n]+2;
00207 }
00208
00209
00210 if (dim == 3) {
00211 int a = (m_[0]+3) * (m_[1]+3);
00212 int b = m_[0]+3;
00213 for ( int i=min[2], index = a*i; i<=max[2]; ++i, index+=a ) {
00214 double b1 = basis_func( i-floor[2], u[2] );
00215 for ( int j=min[1], d = b*j + index; j<=max[1]; ++j, d+=b ) {
00216 double b2 = basis_func( j-floor[1], u[1] );
00217 for ( int k=min[0], e = d+k; k<=max[0]; ++k, ++e ) {
00218 double b3 = basis_func( k-floor[0], u[0] );
00219 br[e] = b1 * b2 * b3;
00220 }
00221 }
00222 }
00223 }
00224
00225 else if (dim == 2) {
00226 int a =(m_[0]+3);
00227 for ( int i=min[1], index = a*i; i<=max[1]; ++i, index+=a ) {
00228 double b1 = basis_func( i-floor[1], u[1] );
00229 for ( int j=min[0], b = j + index; j<=max[0]; ++j, ++b ) {
00230 double b2 = basis_func( j-floor[0], u[0] );
00231 br[b] = b1 * b2;
00232 }
00233 }
00234 }
00235
00236 else if (dim == 1) {
00237 for ( int i=min[0], b = i; i<= max[0]; ++i, ++b ) {
00238 double b1 = basis_func( i-floor[0], u[0] );
00239 br[b] = b1;
00240 }
00241 }
00242 else
00243 assert ( !"dim should be 1, 2 or 3" );
00244 }
00245
00246 double
00247 rgrl_spline::
00248 element_1d_thin_plate(unsigned i, unsigned j) const
00249 {
00250
00251 int a1 = i - 1;
00252 int b1 = j - 1;
00253
00254 if ( vnl_math_abs( a1 - b1 ) > 3 )
00255 return 0;
00256 #if 0
00257 return g( delta_[0], a1, b1, m_[0] ) * delta_[0];
00258 return g_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00259 return g_double_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00260 #endif // 0
00261 return g_double_prime( a1, b1, m_[0] );
00262 }
00263
00264 double
00265 rgrl_spline::
00266 element_2d_thin_plate(unsigned i, unsigned j) const
00267 {
00268
00269
00270 int a1 = i % ( m_[0] + 3 ) - 1;
00271 int a2 = ( i / ( m_[0] + 3 ) ) - 1;
00272
00273 int b1 = j % ( m_[0] + 3 ) - 1;
00274 int b2 = ( j / ( m_[0] + 3 ) ) - 1;
00275
00276 if ( vnl_math_abs( a1 - b1 ) > 3 )
00277 return 0;
00278 if ( vnl_math_abs( a2 - b2 ) > 3 )
00279 return 0;
00280
00281 #if 0
00282 double gx = g( delta_[0], a1, b1, m_[0] ) * delta_[0];
00283 double gx_prime = g_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00284 double gx_double_prime = g_double_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00285
00286 double gy = g( delta_[0], a2, b2, m_[1] ) * delta_[1];
00287 double gy_prime = g_prime( delta_[0], a2, b2, m_[1] ) * delta_[1];
00288 double gy_double_prime = g_double_prime( delta_[0], a2, b2, m_[1] ) * delta_[1];
00289 #else
00290 double gx = g( a1, b1, m_[0] );
00291 double gx_prime = g_prime( a1, b1, m_[0] );
00292 double gx_double_prime = g_double_prime( a1, b1, m_[0] );
00293
00294 double gy = g( a2, b2, m_[1] );
00295 double gy_prime = g_prime( a2, b2, m_[1] );
00296 double gy_double_prime = g_double_prime( a2, b2, m_[1] );
00297 #endif // 0
00298
00299 return gx_double_prime * gy +
00300 gx * gy_double_prime +
00301 2 * gx_prime * gy_prime;
00302 }
00303
00304 double
00305 rgrl_spline::
00306 element_3d_thin_plate(unsigned i, unsigned j) const
00307 {
00308
00309
00310
00311 int a1 = i % ( m_[0] + 3 ) - 1;
00312 int a2 = ( i / ( m_[0] + 3 ) ) % ( m_[1] + 3 ) - 1;
00313 int a3 = ( i / ( m_[0] + 3 ) ) / ( m_[1] + 3 ) - 1;
00314
00315 int b1 = j % ( m_[0] + 3 ) - 1;
00316 int b2 = ( j / ( m_[0] + 3 ) ) % ( m_[1] + 3 ) - 1;
00317 int b3 = ( j / ( m_[0] + 3 ) ) / ( m_[1] + 3 ) - 1;
00318
00319 if ( vnl_math_abs( a1 - b1 ) > 3 )
00320 return 0;
00321 if ( vnl_math_abs( a2 - b2 ) > 3 )
00322 return 0;
00323 if ( vnl_math_abs( a3 - b3 ) > 3 )
00324 return 0;
00325
00326 #if 0
00327 double gx = g( delta_[0], a1, b1, m_[0] ) * delta_[0];
00328 double gx_prime = g_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00329 double gx_double_prime = g_double_prime( delta_[0], a1, b1, m_[0] ) * delta_[0];
00330
00331 double gy = g( delta_[0], a2, b2, m_[1] ) * delta_[1];
00332 double gy_prime = g_prime( delta_[0], a2, b2, m_[1] ) * delta_[1];
00333 double gy_double_prime = g_double_prime( delta_[0], a2, b2, m_[1] ) * delta_[1];
00334
00335 double gz = g( delta_[0], a3, b3, m_[2] ) * delta_[2];
00336 double gz_prime = g_prime( delta_[0], a3, b3, m_[2] ) * delta_[2];
00337 double gz_double_prime = g_double_prime( delta_[0], a3, b3, m_[2] ) * delta_[2];
00338 #else
00339 double gx = g( a1, b1, m_[0] );
00340 double gx_prime = g_prime( a1, b1, m_[0] );
00341 double gx_double_prime = g_double_prime( a1, b1, m_[0] );
00342
00343 double gy = g( a2, b2, m_[1] );
00344 double gy_prime = g_prime( a2, b2, m_[1] );
00345 double gy_double_prime = g_double_prime( a2, b2, m_[1] );
00346
00347 double gz = g( a3, b3, m_[2] );
00348 double gz_prime = g_prime( a3, b3, m_[2] );
00349 double gz_double_prime = g_double_prime( a3, b3, m_[2] );
00350 #endif // 0
00351
00352 return gx_double_prime * gy * gz +
00353 gx * gy_double_prime * gz +
00354 gx * gy * gz_double_prime +
00355 2 * gx_prime * gy_prime * gz +
00356 2 * gx_prime * gy * gz_prime +
00357 2 * gx * gy_prime * gz_prime;
00358 }
00359
00360 void
00361 rgrl_spline::
00362 thin_plate_regularization(vnl_matrix<double>& regularization) const
00363 {
00364 const unsigned dim = m_.size();
00365
00366 double vol = 1;
00367 for ( unsigned i=0; i<dim; ++i ) {
00368 vol *= m_[i];
00369 }
00370
00371 unsigned num = 1;
00372 for ( unsigned i=0; i<dim; ++i ) {
00373 num *= m_[i] + 3;
00374 }
00375
00376 regularization.set_size(num, num);
00377 for ( unsigned i=0; i<num; ++i ) {
00378 for ( unsigned j=i; j<num; ++j ) {
00379 if ( dim == 1 )
00380 regularization[i][j] = regularization[j][i] = element_1d_thin_plate(i, j) / vol;
00381 else if ( dim == 2 )
00382 regularization[i][j] = regularization[j][i] = element_2d_thin_plate(i, j) / vol;
00383 else if ( dim == 3 )
00384 regularization[i][j] = regularization[j][i] = element_3d_thin_plate(i, j) / vol;
00385 }
00386 }
00387 }
00388
00389
00390 double
00391 bspline_basis_function( int i, double u )
00392 {
00393 assert ( u <= 1.0 && u >= 0.0 );
00394 assert ( i <= 3 && i >= 0 );
00395 double b = 0;
00396 double s = 1 - u;
00397
00398 switch (i) {
00399 case 0:
00400 b = s*s*s / 6;
00401 break;
00402 case 1:
00403 b = ( 4 - 3 * u * u * (s+1) ) / 6;
00404 break;
00405 case 2:
00406 b = ( 3 * u * (u*s+1) + 1 ) / 6;
00407 break;
00408 case 3:
00409 b = u*u*u / 6;
00410 break;
00411 default:
00412 vcl_cerr << "rgrl_spline::basis_function: wrong index for basis functions : " << i << '\n';
00413 }
00414 return b;
00415 }
00416
00417 double
00418 bspline_basis_prime_function( int i, double u )
00419 {
00420 assert ( u <= 1 && u >= 0 );
00421 assert ( i <= 3 && i >= 0 );
00422 double b = 0;
00423 double s = 1 - u;
00424
00425 switch (i) {
00426 case 0:
00427 b = - s*s / 2;
00428 break;
00429 case 1:
00430 b = - u * (3*s+1) / 2;
00431 break;
00432 case 2:
00433 b = s * (3*u+1) / 2;
00434 break;
00435 case 3:
00436 b = u*u / 2;
00437 break;
00438 default:
00439 vcl_cerr << "rgrl_spline::basis_function: wrong index for basis functions\n";
00440 }
00441 return b;
00442 }
00443
00444 static
00445 double
00446 g( int a1, int a2, int m )
00447 {
00448 int min_a, max_a;
00449 if ( a1 < a2 ) {
00450 min_a = a1;
00451 max_a = a2;
00452 }
00453 else {
00454 min_a = a2;
00455 max_a = a1;
00456 }
00457
00458 assert ( min_a >= -1 );
00459 assert ( max_a <= m+1 );
00460 int diff_a = vnl_math_abs( a1 - a2 );
00461
00462 double ans = 0;
00463 if ( diff_a == 0 ) {
00464 double ans = 0;
00465 if ( max_a <= m-2 ) {
00466
00467 ans += 1.0 / 252 ;
00468 }
00469 if ( min_a >= 0 && max_a <= m-1 ) {
00470
00471 ans += 0.2 + 1.0 / 28;
00472 }
00473 if ( min_a >= 1 && max_a <= m ) {
00474
00475 ans += 0.2 + 1.0 / 28;
00476 }
00477 if ( min_a >= 2 ) {
00478
00479 ans += 1.0 / 252;
00480 }
00481 return ans;
00482 }
00483
00484 if ( diff_a == 1 ) {
00485 if ( max_a <= m-1 ) {
00486
00487 ans += 0.0375 - 1.0 / 84;
00488 }
00489 if ( min_a >= 0 && max_a <= m ) {
00490
00491 ans += -0.1125 - 1.0 / 28 + 1.0 / 3;
00492 }
00493 if ( min_a >= 1 ) {
00494
00495 ans += 0.0375 - 1.0 / 84;
00496 }
00497 return ans;
00498 }
00499
00500 if ( diff_a == 2 ) {
00501 if ( max_a <= m ) {
00502
00503 ans += 1.0 / 84;
00504 }
00505 if ( min_a >= 0 ) {
00506
00507 ans += 1.0 / 84;
00508 }
00509 return ans;
00510 }
00511
00512 if ( diff_a == 3 ) {
00513
00514 ans += 1.0 / 240 - 1.0 / 252;
00515 return ans;
00516 }
00517
00518 return 0;
00519 }
00520
00521 static
00522 double
00523 g_prime( int a1, int a2, int m )
00524 {
00525 int min_a = (a1 < a2) ? a1 : a2;
00526 int max_a = (a1 < a2) ? a2 : a1;
00527 assert ( min_a >= -1 );
00528 assert ( max_a <= m+1 );
00529 int diff_a = vnl_math_abs( a1 - a2 );
00530
00531 double ans = 0;
00532 if ( diff_a == 0 ) {
00533 if ( max_a <= m-2 ) {
00534
00535 ans += 0.05;
00536 }
00537 if ( min_a >= 0 && max_a <= m-1 ) {
00538
00539 ans += 0.2 + 1.0 / 12;
00540 }
00541 if ( min_a >= 1 && max_a <= m ) {
00542
00543 ans += 0.2 + 1.0 / 12;
00544 }
00545 if ( min_a >= 2 ) {
00546
00547 ans += 0.05;
00548 }
00549 return ans;
00550 }
00551
00552 if ( diff_a == 1 ) {
00553 if ( max_a <= m-1 ) {
00554
00555 ans += -0.025 + 1.0 / 12;
00556 }
00557 if ( min_a >= 0 && max_a <= m) {
00558
00559 ans += 0.175 - 5.0 / 12;
00560 }
00561 if ( min_a >= 1 ) {
00562
00563 ans += -0.025 + 1.0 / 12;
00564 }
00565 return ans;
00566 }
00567
00568 if ( diff_a == 2 ) {
00569 if ( max_a <= m ) {
00570
00571 ans += -0.1;
00572 }
00573 if ( min_a >= 0 ) {
00574
00575 ans += -0.1;
00576 }
00577 return ans;
00578 }
00579
00580 if ( diff_a == 3 ) {
00581
00582 ans += 0.075 - 1.0 / 12;
00583 return ans;
00584 }
00585
00586 return 0;
00587 }
00588
00589 static
00590 double
00591 g_double_prime( int a1, int a2, int m )
00592 {
00593 int min_a = (a1 < a2) ? a1 : a2;
00594 int max_a = (a1 < a2) ? a2 : a1;
00595 assert ( min_a >= -1 );
00596 assert ( max_a <= m+1 );
00597 int diff_a = vnl_math_abs( a1 - a2 );
00598
00599 double ans = 0;
00600 if ( diff_a == 0 ) {
00601 if ( max_a <= m-2 ) {
00602
00603 ans += 1.0 / 3;
00604 }
00605 if ( min_a >= 0 && max_a <= m-1 ) {
00606
00607 ans += 1.0;
00608 }
00609 if ( min_a >= 1 && max_a <= m ) {
00610
00611 ans += 1.0;
00612 }
00613 if ( min_a >= 2 ) {
00614
00615 ans += 1.0 / 3;
00616 }
00617 return ans;
00618 }
00619
00620 if ( diff_a == 1 ) {
00621 if ( max_a <= m-1 ) {
00622
00623 ans += -0.5;
00624 }
00625 if ( min_a >= 0 && max_a <= m) {
00626
00627 ans += -0.5;
00628 }
00629 if ( min_a >= 1 ) {
00630
00631 ans += -0.5;
00632 }
00633 return ans;
00634 }
00635
00636 if ( diff_a == 2 ) {
00637
00638
00639
00640
00641 return ans;
00642 }
00643
00644 if ( diff_a == 3 ) {
00645
00646 ans += 0.5 - 1.0 / 3;
00647 return ans;
00648 }
00649
00650 return 0;
00651 }
00652
00653 static
00654 inline
00655 double
00656 refine_helper_f1( double v1, double v2)
00657 {
00658 return ( v1 + v2 ) / 2;
00659 }
00660
00661 static
00662 inline
00663 double
00664 refine_helper_f2( double v1, double v2, double v3 )
00665 {
00666 return v1 / 8 + v2 * 3 / 4 + v3 / 8;
00667 }
00668
00669 rgrl_spline_sptr
00670 rgrl_spline::
00671 refinement( vnl_vector< unsigned > const& m ) const
00672 {
00673 const unsigned dim = m_.size();
00674 rgrl_spline_sptr refined_spline = new rgrl_spline( m );
00675 vnl_vector< double > w( refined_spline->num_of_control_points() );
00676
00677
00678 if ( dim == 1 )
00679 {
00680 for ( unsigned i = 0; i<m_[0]+2; ++i ) {
00681
00682 if ( 2*i < m[0]+3 )
00683 w[2*i] = refine_helper_f1( c_[i], c_[i+1] );
00684
00685 if ( i!=m_[0]+1 && 2*i+1 < m[0]+3 )
00686 w[2*i+1] = refine_helper_f2( c_[i], c_[i+1], c_[i+2] );
00687 }
00688 }
00689 else if ( dim == 2 )
00690 {
00691 vcl_vector< double > tmp( m_[1] + 3, 0.0 );
00692 vcl_vector< vcl_vector< double > > v2( m_[0] + 1, tmp );
00693 vcl_vector< vcl_vector< double > > v1( m_[0] + 2, tmp );
00694 unsigned a = m_[0]+3;
00695
00696 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00697 for ( unsigned j=0, n=i; j<m_[1]+3; ++j, n+=a ) {
00698 v1[i][j] = refine_helper_f1( c_[n], c_[n+1] );
00699 if ( i!=m_[0]+1 )
00700 v2[i][j] = refine_helper_f2( c_[n], c_[n+1], c_[n+2] );
00701 }
00702 }
00703 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00704 for ( unsigned j=0; j<m_[1]+2; ++j ) {
00705
00706 if ( 2*i < m[0]+3 && 2*j < m[1]+3 ) {
00707 w[2*i + 2*j*(m[0]+3)] = refine_helper_f1( v1[i][j], v1[i][j+1] );
00708 }
00709 if ( i!=m_[0]+1 && 2*i+1 < m[0]+3 && 2*j < m[1]+3 ) {
00710 w[2*i+1 + 2*j*(m[0]+3)] = refine_helper_f1( v2[i][j], v2[i][j+1] );
00711 }
00712
00713 if ( j!=m_[1]+1 && 2*i < m[0]+3 && 2*j+1 < m[1]+3 ) {
00714 w[2*i + (2*j+1)*(m[0]+3)] = refine_helper_f2( v1[i][j], v1[i][j+1], v1[i][j+2] );
00715 }
00716 if ( i!=m_[0]+1 && j!=m_[1]+1 && 2*i+1 < m[0]+3 && 2*j+1 < m[1]+3 ) {
00717 w[2*i+1 + (2*j+1)*(m[0]+3)] = refine_helper_f2( v2[i][j], v2[i][j+1], v2[i][j+2] );
00718 }
00719 }
00720 }
00721 }
00722 else if ( dim == 3 )
00723 {
00724 vcl_vector< double > tmp( m_[2] + 3, 0.0 );
00725 vcl_vector< vcl_vector< double > > tmp1( m_[1] + 3, tmp );
00726 vcl_vector< vcl_vector< double > > tmp2( m_[1] + 1, tmp );
00727 vcl_vector< vcl_vector< double > > tmp3( m_[1] + 2, tmp );
00728 vcl_vector< vcl_vector< vcl_vector< double > > > v2( m_[0] + 1, tmp1 );
00729 vcl_vector< vcl_vector< vcl_vector< double > > > v1( m_[0] + 2, tmp1 );
00730 vcl_vector< vcl_vector< vcl_vector< double > > > v12( m_[0]+2, tmp2 );
00731 vcl_vector< vcl_vector< vcl_vector< double > > > v22( m_[0]+1, tmp2 );
00732 vcl_vector< vcl_vector< vcl_vector< double > > > v11( m_[0]+2, tmp3 );
00733 vcl_vector< vcl_vector< vcl_vector< double > > > v21( m_[0]+1, tmp3 );
00734
00735 unsigned b = m_[1]+3;
00736 unsigned a = m_[0]+3;
00737 unsigned ab = a * b;
00738 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00739 for ( unsigned j=0; j<m_[1]+3; ++j ) {
00740 for ( unsigned k=0, n=j*a+i; k<m_[2]+3; ++k, n+=ab ) {
00741 v1[i][j][k] = refine_helper_f1( c_[n], c_[n+1] );
00742 if ( i!=m_[0]+1 )
00743 v2[i][j][k] = refine_helper_f2( c_[n], c_[n+1], c_[n+2] );
00744 }
00745 }
00746 }
00747
00748 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00749 for ( unsigned j=0; j<m_[1]+2; ++j ) {
00750 for ( unsigned k=0; k<m_[2]+3; ++k ) {
00751 v11[i][j][k] = refine_helper_f1( v1[i][j][k], v1[i][j+1][k] );
00752 if ( i!=m_[0]+1 )
00753 v21[i][j][k] = refine_helper_f1( v2[i][j][k], v2[i][j+1][k] );
00754 if ( j!=m_[1]+1 )
00755 v12[i][j][k] = refine_helper_f2( v1[i][j][k], v1[i][j+1][k], v1[i][j+2][k] );
00756 if ( i!=m_[0]+1 && j!=m_[1]+1 )
00757 v22[i][j][k] = refine_helper_f2( v2[i][j][k], v2[i][j+1][k], v2[i][j+2][k] );
00758 }
00759 }
00760 }
00761
00762 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00763 for ( unsigned j=0; j<m_[1]+2; ++j ) {
00764 for ( unsigned k=0; k<m_[2]+2; ++k ) {
00765
00766 if ( 2*i < m[0]+3 && 2*j < m[1]+3 && 2*k < m[2]+3 )
00767 w[2*i + 2*j*(m[0]+3) + 2*k*(m[0]+3)*(m[1]+3)] =
00768 refine_helper_f1( v11[i][j][k], v11[i][j][k+1] ) ;
00769 if ( i!=m_[0]+1 && 2*i+1 < m[0]+3 && 2*j < m[1]+3 && 2*k < m[2]+3 )
00770 w[2*i+1 + 2*j*(m[0]+3) + 2*k*(m[0]+3)*(m[1]+3) ] =
00771 refine_helper_f1( v21[i][j][k], v21[i][j][k+1] );
00772 if ( j!=m_[1]+1 && 2*i < m[0]+3 && 2*j+1 < m[1]+3 && 2*k < m[2]+3 )
00773 w[2*i + (2*j+1)*(m[0]+3) + 2*k*(m[0]+3)*(m[1]+3)] =
00774 refine_helper_f1( v12[i][j][k], v12[i][j][k+1] );
00775 if ( i!=m_[0]+1 && j!=m_[1]+1 && 2*i+1 < m[0]+3 && 2*j+1 < m[1]+3 && 2*k < m[2]+3 )
00776 w[2*i+1 + (2*j+1)*(m[0]+3) + 2*k*(m[0]+3)*(m[1]+3) ] =
00777 refine_helper_f1( v22[i][j][k], v22[i][j][k+1] );
00778
00779
00780 if ( k!=m_[2]+1 && 2*i < m[0]+3 && 2*j < m[1]+3 && 2*k+1 < m[2]+3 )
00781 w[2*i + 2*j*(m[0]+3) + (2*k+1)*(m[0]+3)*(m[1]+3)] =
00782 refine_helper_f2( v11[i][j][k], v11[i][j][k+1], v11[i][j][k+2] );
00783 if ( i!=m_[0]+1 && k!=m_[2]+1 && 2*i+1 < m[0]+3 && 2*j < m[1]+3 && 2*k+1 < m[2]+3 )
00784 w[2*i+1 + 2*j*(m[0]+3) + (2*k+1)*(m[0]+3)*(m[1]+3) ] =
00785 refine_helper_f2( v21[i][j][k], v21[i][j][k+1], v21[i][j][k+2] );
00786 if ( j!=m_[1]+1 && k!=m_[2]+1 && 2*i < m[0]+3 && 2*j+1 < m[1]+3 && 2*k+1 < m[2]+3 )
00787 w[2*i + (2*j+1)*(m[0]+3) + (2*k+1)*(m[0]+3)*(m[1]+3)] =
00788 refine_helper_f2( v12[i][j][k], v12[i][j][k+1], v12[i][j][k+2] );
00789 if ( i!=m_[0]+1 && j!=m_[1]+1 && k!=m_[2]+1 && 2*i+1 < m[0]+3 && 2*j+1 < m[1]+3 && 2*k+1 < m[2]+3 )
00790 w[2*i+1 +(2*j+1)*(m[0]+3) + (2*k+1)*(m[0]+3)*(m[1]+3) ] =
00791 refine_helper_f2( v22[i][j][k], v22[i][j][k+1], v22[i][j][k+2] );
00792 }
00793 }
00794 }
00795 #if 0
00796 for ( unsigned i=0; i<m_[0]+2; ++i ) {
00797 for ( unsigned j=0; j<m_[1]+2; ++j ) {
00798 for ( unsigned k=0; k<m_[2]+2; ++k ) {
00799
00800 w[2*i + 2*j*(2*m_[0]+3) + 2*k*(2*m_[0]+3)*(2*m_[1]+3)] =
00801 refine_helper_f1( v11[i][j][k], v11[i][j][k+1] ) ;
00802 if ( i!=m_[0]+1 )
00803 w[2*i+1 + 2*j*(2*m_[0]+3) + 2*k*(2*m_[0]+3)*(2*m_[1]+3) ] =
00804 refine_helper_f1( v21[i][j][k], v21[i][j][k+1] );
00805 if ( j!=m_[1]+1 )
00806 w[2*i + (2*j+1)*(2*m_[0]+3) + 2*k*(2*m_[0]+3)*(2*m_[1]+3)] =
00807 refine_helper_f1( v12[i][j][k], v12[i][j][k+1] );
00808 if ( i!=m_[0]+1 && j!=m_[1]+1 )
00809 w[2*i+1 + (2*j+1)*(2*m_[0]+3) + 2*k*(2*m_[0]+3)*(2*m_[1]+3) ] =
00810 refine_helper_f1( v22[i][j][k], v22[i][j][k+1] );
00811
00812
00813 if ( k!=m_[2]+1 )
00814 w[2*i + 2*j*(2*m_[0]+3) + (2*k+1)*(2*m_[0]+3)*(2*m_[1]+3)] =
00815 refine_helper_f2( v11[i][j][k], v11[i][j][k+1], v11[i][j][k+2] );
00816 if ( i!=m_[0]+1 && k!=m_[2]+1 )
00817 w[2*i+1 + 2*j*(2*m_[0]+3) + (2*k+1)*(2*m_[0]+3)*(2*m_[1]+3) ] =
00818 refine_helper_f2( v21[i][j][k], v21[i][j][k+1], v21[i][j][k+2] );
00819 if ( j!=m_[1]+1 && k!=m_[2]+1 )
00820 w[2*i + (2*j+1)*(2*m_[0]+3) + (2*k+1)*(2*m_[0]+3)*(2*m_[1]+3)] =
00821 refine_helper_f2( v12[i][j][k], v12[i][j][k+1], v12[i][j][k+2] );
00822 if ( i!=m_[0]+1 && j!=m_[1]+1 && k!=m_[2]+1 )
00823 w[2*i+1 +(2*j+1)*(2*m_[0]+3) + (2*k+1)*(2*m_[0]+3)*(2*m_[1]+3) ] =
00824 refine_helper_f2( v22[i][j][k], v22[i][j][k+1], v22[i][j][k+2] );
00825 }
00826 }
00827 }
00828 #endif // 0
00829 }
00830 else
00831 assert ( !"dim should be 1, 2 or 3" );
00832
00833 #ifdef DEBUG
00834 vcl_cout << "rgrl_spline.cxx: refinement set_control_points: " << w << vcl_endl;
00835 #endif
00836 refined_spline->set_control_points( w );
00837 return refined_spline;
00838 }
00839
00840
00841 vcl_ostream&
00842 operator<< (vcl_ostream& os, rgrl_spline const& spline )
00843 {
00844
00845 os << spline.m_.size() << ' '
00846 << spline.m_ << vcl_endl;
00847
00848
00849 os << spline.c_.size() << vcl_endl
00850 << spline.c_;
00851
00852
00853 return os;
00854 }
00855
00856 vcl_istream&
00857 operator>> (vcl_istream& is, rgrl_spline& spline )
00858 {
00859 int s;
00860
00861 s=-1;
00862 is >> s;
00863 spline.m_.set_size( s );
00864 is >> spline.m_;
00865
00866
00867 s=-1;
00868 is >> s;
00869 spline.c_.set_size( s );
00870 is >> spline.c_;
00871
00872 return is;
00873 }
00874
00875 #if 0
00876 bool
00877 rgrl_spline::
00878 is_support( vnl_vector< double > const& pt, unsigned index )
00879 {
00880 assert ( pt.size() == m_.size() );
00881 const unsigned dim = pt.size();
00882
00883 for ( unsigned i=0; i<m_.size(); ++i )
00884 if ( pt[i] < -3 || pt[i] >= m_[i]+3 )
00885 return false;
00886
00887 vnl_vector< int > floor(dim);
00888 vnl_vector< int > ceil(dim);
00889
00890 for ( unsigned n=0; n<dim; ++n ) {
00891 floor[n] = (int)vcl_floor( pt[n] ) ;
00892 ceil[n] = (int)vcl_ceil( pt[n] );
00893 }
00894
00895
00896 if (dim == 3) {
00897 int a = (m_[0]+3) * (m_[1]+3);
00898 int b = m_[0]+3;
00899
00900 unsigned blk[ 3 ];
00901 blk[ 0 ] = index % b;
00902 blk[ 1 ] = index % a / b;
00903 blk[ 2 ] = index / a;
00904
00905 for ( unsigned i = 0; i < dim; ++i )
00906 if ( blk[i] < floor[i] || blk[i] > ceil[i]+2 )
00907 return false;
00908 }
00909
00910 else if (dim == 2) {
00911 int a =(m_[0]+3);
00912 unsigned blk[ 2 ];
00913 blk[ 0 ] = index % a;
00914 blk[ 1 ] = index / a;
00915
00916 for ( unsigned i = 0; i < dim; ++i )
00917 if ( blk[i] < floor[i] || blk[i] > ceil[i]+2 )
00918 return false;
00919 }
00920
00921 else if (dim == 1) {
00922 if ( index < floor[0] || index > ceil[0]+2 )
00923 return false;
00924 }
00925 return true;
00926 }
00927 #endif // 0