00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <iostream>
00011 #include <limits>
00012
00013 #include <ApproxMVBB/Diameter/Utils/util.hpp>
00014
00015 namespace ApproxMVBB{
00016 namespace Diameter{
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 int _LastPointOutsideSphereWithDiameter( TypeSegment *theSeg,
00045 const double squareDiameter,
00046 const double **theList,
00047 const int first,
00048 int *last,
00049 const int dim,
00050 const int _reduction_mode_ )
00051 {
00052 int i;
00053 int index = first - 1;
00054 int l = *last;
00055
00056 double mamb, am2;
00057
00058 double minThreshold;
00059 double medThreshold;
00060 double maxThreshold;
00061
00062 double ab = sqrt( theSeg->squareDiameter );
00063 double ab2 = theSeg->squareDiameter;
00064
00065 double R = sqrt( squareDiameter );
00066 double R2 = squareDiameter;
00067
00068 if ( first > *last ) return( first - 1 );
00069
00070 if ( squareDiameter <= theSeg->squareDiameter ) {
00071
00072 maxThreshold = medThreshold = 0.0;
00073 minThreshold = -0.23205080756887729352 * theSeg->squareDiameter;
00074
00075 } else {
00076
00077 minThreshold = (R - .86602540378443864676*ab)
00078 * (R - .86602540378443864676*ab)
00079 - 0.25 * ab2;
00080
00081 medThreshold = 0.5 * ab2 + 0.25 * R2
00082 - .43301270189221932338 * R * sqrt( 4 * ab2 - R2 );
00083
00084 maxThreshold = 0.25 * (R2 - ab2);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 switch ( _reduction_mode_ ) {
00094
00095 case 0 :
00096
00097
00098
00099 if ( dim == 2 ) {
00100 for ( i=first; i<=l; i++ ) {
00101 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00102 theList[i], theSeg->extremity2 );
00103 if ( mamb > maxThreshold ) {
00104 index ++;
00105 _SwapPoints( theList, index, i );
00106 }
00107 }
00108 return( index );
00109 }
00110
00111 if ( dim == 3 ) {
00112 for ( i=first; i<=l; i++ ) {
00113 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00114 theList[i], theSeg->extremity2 );
00115 if ( mamb > maxThreshold ) {
00116 index ++;
00117 _SwapPoints( theList, index, i );
00118 }
00119 }
00120 return( index );
00121 }
00122
00123 for ( i=first; i<=l; i++ ) {
00124 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00125 theList[i], theSeg->extremity2, dim );
00126 if ( mamb > maxThreshold ) {
00127 index ++;
00128 _SwapPoints( theList, index, i );
00129 }
00130 }
00131 return( index );
00132
00133
00134
00135
00136 break;
00137
00138 default :
00139 case 1 :
00140
00141
00142
00143
00144 if ( dim == 2 ) {
00145 for ( i=first; i<=l; i++ ) {
00146 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00147 theList[i], theSeg->extremity2 );
00148 if ( mamb > maxThreshold ) {
00149 index ++;
00150 _SwapPoints( theList, index, i );
00151 }
00152 else if ( mamb <= minThreshold ) {
00153 _SwapPoints( theList, i, l );
00154 i--; l--;
00155 }
00156 }
00157 *last = l;
00158 return( index );
00159 }
00160
00161 if ( dim == 3 ) {
00162 for ( i=first; i<=l; i++ ) {
00163 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00164 theList[i], theSeg->extremity2 );
00165 if ( mamb > maxThreshold ) {
00166 index ++;
00167 _SwapPoints( theList, index, i );
00168 }
00169 else if ( mamb <= minThreshold ) {
00170 _SwapPoints( theList, i, l );
00171 i--; l--;
00172 }
00173 }
00174 *last = l;
00175 return( index );
00176 }
00177
00178 for ( i=first; i<=l; i++ ) {
00179 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00180 theList[i], theSeg->extremity2, dim );
00181 if ( mamb > maxThreshold ) {
00182 index ++;
00183 _SwapPoints( theList, index, i );
00184 }
00185 else if ( mamb <= minThreshold ) {
00186 _SwapPoints( theList, i, l );
00187 i--; l--;
00188 }
00189 }
00190 *last = l;
00191 return( index );
00192
00193
00194
00195
00196 break;
00197
00198 case 2 :
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 if ( dim == 2 ) {
00211
00212 if ( squareDiameter <= theSeg->squareDiameter ) {
00213
00214 for ( i=first; i<=l; i++ ) {
00215 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00216 theList[i], theSeg->extremity2 );
00217 if ( mamb > maxThreshold ) {
00218 index ++;
00219 _SwapPoints( theList, index, i );
00220 }
00221 else if ( mamb > minThreshold ) {
00222 am2 = _SquareDistance2D( theList[i], theSeg->extremity1 );
00223 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00224 _SwapPoints( theList, i, l );
00225 i--; l--;
00226 }
00227 }
00228 else {
00229
00230 _SwapPoints( theList, i, l );
00231 i--; l--;
00232 }
00233 }
00234
00235 } else {
00236
00237 for ( i=first; i<=l; i++ ) {
00238 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00239 theList[i], theSeg->extremity2 );
00240 if ( mamb > maxThreshold ) {
00241 index ++;
00242 _SwapPoints( theList, index, i );
00243 }
00244 else if ( mamb > medThreshold ) {
00245 continue;
00246 }
00247 else if ( mamb > minThreshold ) {
00248 am2 = _SquareDistance2D( theList[i], theSeg->extremity1 );
00249 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00250 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00251 _SwapPoints( theList, i, l );
00252 i--; l--;
00253 }
00254 }
00255 else {
00256
00257 _SwapPoints( theList, i, l );
00258 i--; l--;
00259 }
00260 }
00261
00262 }
00263 *last = l;
00264 return( index );
00265 }
00266
00267 if ( dim == 3 ) {
00268
00269 if ( squareDiameter <= theSeg->squareDiameter ) {
00270
00271 for ( i=first; i<=l; i++ ) {
00272 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00273 theList[i], theSeg->extremity2 );
00274 if ( mamb > maxThreshold ) {
00275 index ++;
00276 _SwapPoints( theList, index, i );
00277 }
00278 else if ( mamb > minThreshold ) {
00279 am2 = _SquareDistance3D( theList[i], theSeg->extremity1 );
00280 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00281 _SwapPoints( theList, i, l );
00282 i--; l--;
00283 }
00284 }
00285 else {
00286
00287 _SwapPoints( theList, i, l );
00288 i--; l--;
00289 }
00290 }
00291
00292 } else {
00293
00294 for ( i=first; i<=l; i++ ) {
00295 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00296 theList[i], theSeg->extremity2 );
00297 if ( mamb > maxThreshold ) {
00298 index ++;
00299 _SwapPoints( theList, index, i );
00300 }
00301 else if ( mamb > medThreshold ) {
00302 continue;
00303 }
00304 else if ( mamb > minThreshold ) {
00305 am2 = _SquareDistance3D( theList[i], theSeg->extremity1 );
00306 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00307 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00308 _SwapPoints( theList, i, l );
00309 i--; l--;
00310 }
00311 }
00312 else {
00313
00314 _SwapPoints( theList, i, l );
00315 i--; l--;
00316 }
00317 }
00318
00319 }
00320 *last = l;
00321 return( index );
00322 }
00323
00324 if ( squareDiameter <= theSeg->squareDiameter ) {
00325
00326 for ( i=first; i<=l; i++ ) {
00327 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00328 theList[i], theSeg->extremity2, dim );
00329 if ( mamb > maxThreshold ) {
00330 index ++;
00331 _SwapPoints( theList, index, i );
00332 }
00333 else if ( mamb > minThreshold ) {
00334 am2 = _SquareDistance( theList[i], theSeg->extremity1, dim );
00335 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00336 _SwapPoints( theList, i, l );
00337 i--; l--;
00338 }
00339 }
00340 else {
00341
00342 _SwapPoints( theList, i, l );
00343 i--; l--;
00344 }
00345 }
00346
00347 } else {
00348
00349 for ( i=first; i<=l; i++ ) {
00350 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00351 theList[i], theSeg->extremity2, dim );
00352 if ( mamb > maxThreshold ) {
00353 index ++;
00354 _SwapPoints( theList, index, i );
00355 }
00356 else if ( mamb > medThreshold ) {
00357 continue;
00358 }
00359 else if ( mamb > minThreshold ) {
00360 am2 = _SquareDistance( theList[i], theSeg->extremity1, dim );
00361 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00362 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00363 _SwapPoints( theList, i, l );
00364 i--; l--;
00365 }
00366 }
00367 else {
00368
00369 _SwapPoints( theList, i, l );
00370 i--; l--;
00371 }
00372 }
00373
00374 }
00375 *last = l;
00376 return( index );
00377
00378
00379
00380
00381 }
00382 return( -1 );
00383 }
00384
00385
00386 int _LastPointOutsideSphereAndBoundWithDiameter( TypeSegment *theSeg,
00387 const double squareDiameter,
00388 const double **theList,
00389 const int first,
00390 int *last,
00391 const int dim,
00392 const int _reduction_mode_,
00393 double *bound )
00394 {
00395 int i;
00396 int index = first - 1;
00397 int l = *last;
00398
00399 double mamb, am2;
00400
00401 double minThreshold;
00402 double medThreshold;
00403 double maxThreshold;
00404
00405 double ab = sqrt( theSeg->squareDiameter );
00406 double ab2 = theSeg->squareDiameter;
00407
00408 double R = sqrt( squareDiameter );
00409 double R2 = squareDiameter;
00410
00411
00412
00413
00414
00415
00416
00417 double b = *bound = (- theSeg->squareDiameter * 0.25);
00418
00419
00420 if ( squareDiameter <= theSeg->squareDiameter ) {
00421
00422 maxThreshold = medThreshold = 0.0;
00423 minThreshold = -0.23205080756887729352 * theSeg->squareDiameter;
00424
00425 return( _LastPointOutsideSphereWithDiameter( theSeg, squareDiameter,
00426 theList, first, last, dim,
00427 _reduction_mode_ ) );
00428
00429 } else {
00430
00431 minThreshold = (R - .86602540378443864676*ab)
00432 * (R - .86602540378443864676*ab)
00433 - 0.25 * ab2;
00434
00435 medThreshold = 0.5 * ab2 + 0.25 * R2
00436 - .43301270189221932338 * R * sqrt( 4 * ab2 - R2 );
00437
00438 maxThreshold = 0.25 * (R2 - ab2);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 switch ( _reduction_mode_ ) {
00448
00449 case 0 :
00450
00451
00452
00453 if ( dim == 2 ) {
00454 for ( i=first; i<=l; i++ ) {
00455 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00456 theList[i], theSeg->extremity2 );
00457 if ( mamb > maxThreshold ) {
00458 index ++;
00459 _SwapPoints( theList, index, i );
00460 continue;
00461 }
00462 if ( b < mamb ) b = mamb;
00463 }
00464 *bound = b;
00465 return( index );
00466 }
00467
00468 if ( dim == 3 ) {
00469 for ( i=first; i<=l; i++ ) {
00470 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00471 theList[i], theSeg->extremity2 );
00472 if ( mamb > maxThreshold ) {
00473 index ++;
00474 _SwapPoints( theList, index, i );
00475 continue;
00476 }
00477 if ( b < mamb ) b = mamb;
00478 }
00479 *bound = b;
00480 return( index );
00481 }
00482
00483 for ( i=first; i<=l; i++ ) {
00484 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00485 theList[i], theSeg->extremity2, dim );
00486 if ( mamb > maxThreshold ) {
00487 index ++;
00488 _SwapPoints( theList, index, i );
00489 continue;
00490 }
00491 if ( b < mamb ) b = mamb;
00492 }
00493 *bound = b;
00494 return( index );
00495
00496
00497
00498
00499 break;
00500
00501 default :
00502 case 1 :
00503
00504
00505
00506
00507 if ( dim == 2 ) {
00508 for ( i=first; i<=l; i++ ) {
00509 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00510 theList[i], theSeg->extremity2 );
00511 if ( mamb > maxThreshold ) {
00512 index ++;
00513 _SwapPoints( theList, index, i );
00514 continue;
00515 }
00516 if ( mamb <= minThreshold ) {
00517 _SwapPoints( theList, i, l );
00518 i--; l--;
00519 continue;
00520 }
00521 if ( b < mamb ) b = mamb;
00522 }
00523 *last = l;
00524 *bound = b;
00525 return( index );
00526 }
00527
00528 if ( dim == 3 ) {
00529 for ( i=first; i<=l; i++ ) {
00530 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00531 theList[i], theSeg->extremity2 );
00532 if ( mamb > maxThreshold ) {
00533 index ++;
00534 _SwapPoints( theList, index, i );
00535 continue;
00536 }
00537 if ( mamb <= minThreshold ) {
00538 _SwapPoints( theList, i, l );
00539 i--; l--;
00540 continue;
00541 }
00542 if ( b < mamb ) b = mamb;
00543 }
00544 *last = l;
00545 *bound = b;
00546 return( index );
00547 }
00548
00549 for ( i=first; i<=l; i++ ) {
00550 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00551 theList[i], theSeg->extremity2, dim );
00552 if ( mamb > maxThreshold ) {
00553 index ++;
00554 _SwapPoints( theList, index, i );
00555 continue;
00556 }
00557 if ( mamb <= minThreshold ) {
00558 _SwapPoints( theList, i, l );
00559 i--; l--;
00560 continue;
00561 }
00562 if ( b < mamb ) b = mamb;
00563 }
00564 *last = l;
00565 *bound = b;
00566 return( index );
00567
00568
00569
00570
00571 break;
00572
00573 case 2 :
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 if ( dim == 2 ) {
00586
00587 if ( squareDiameter <= theSeg->squareDiameter ) {
00588
00589 for ( i=first; i<=l; i++ ) {
00590 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00591 theList[i], theSeg->extremity2 );
00592 if ( mamb > maxThreshold ) {
00593 index ++;
00594 _SwapPoints( theList, index, i );
00595 continue;
00596 }
00597 if ( mamb > minThreshold ) {
00598 am2 = _SquareDistance2D( theList[i], theSeg->extremity1 );
00599 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00600 _SwapPoints( theList, i, l );
00601 i--; l--;
00602 continue;
00603 }
00604 if ( b < mamb ) b = mamb;
00605 continue;
00606 }
00607
00608 _SwapPoints( theList, i, l );
00609 i--; l--;
00610 }
00611
00612 } else {
00613
00614 for ( i=first; i<=l; i++ ) {
00615 mamb = _ScalarProduct2D( theList[i], theSeg->extremity1,
00616 theList[i], theSeg->extremity2 );
00617 if ( mamb > maxThreshold ) {
00618 index ++;
00619 _SwapPoints( theList, index, i );
00620 continue;
00621 }
00622 if ( mamb > medThreshold ) {
00623 if ( b < mamb ) b = mamb;
00624 continue;
00625 }
00626 if ( mamb > minThreshold ) {
00627 am2 = _SquareDistance2D( theList[i], theSeg->extremity1 );
00628 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00629 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00630 _SwapPoints( theList, i, l );
00631 i--; l--;
00632 continue;
00633 }
00634 if ( b < mamb ) b = mamb;
00635 continue;
00636 }
00637
00638 _SwapPoints( theList, i, l );
00639 i--; l--;
00640 }
00641
00642 }
00643 *last = l;
00644 *bound = b;
00645 return( index );
00646 }
00647
00648 if ( dim == 3 ) {
00649
00650 if ( squareDiameter <= theSeg->squareDiameter ) {
00651
00652 for ( i=first; i<=l; i++ ) {
00653 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00654 theList[i], theSeg->extremity2 );
00655 if ( mamb > maxThreshold ) {
00656 index ++;
00657 _SwapPoints( theList, index, i );
00658 continue;
00659 }
00660 if ( mamb > minThreshold ) {
00661 am2 = _SquareDistance3D( theList[i], theSeg->extremity1 );
00662 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00663 _SwapPoints( theList, i, l );
00664 i--; l--;
00665 continue;
00666 }
00667 if ( b < mamb ) b = mamb;
00668 continue;
00669 }
00670
00671 _SwapPoints( theList, i, l );
00672 i--; l--;
00673 }
00674
00675 } else {
00676
00677 for ( i=first; i<=l; i++ ) {
00678 mamb = _ScalarProduct3D( theList[i], theSeg->extremity1,
00679 theList[i], theSeg->extremity2 );
00680 if ( mamb > maxThreshold ) {
00681 index ++;
00682 _SwapPoints( theList, index, i );
00683 continue;
00684 }
00685 if ( mamb > medThreshold ) {
00686 if ( b < mamb ) b = mamb;
00687 continue;
00688 }
00689 if ( mamb > minThreshold ) {
00690 am2 = _SquareDistance3D( theList[i], theSeg->extremity1 );
00691 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00692 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00693 _SwapPoints( theList, i, l );
00694 i--; l--;
00695 continue;
00696 }
00697 if ( b < mamb ) b = mamb;
00698 continue;
00699 }
00700
00701 _SwapPoints( theList, i, l );
00702 i--; l--;
00703 }
00704
00705 }
00706 *last = l;
00707 *bound = b;
00708 return( index );
00709 }
00710
00711 if ( squareDiameter <= theSeg->squareDiameter ) {
00712
00713 for ( i=first; i<=l; i++ ) {
00714 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00715 theList[i], theSeg->extremity2, dim );
00716 if ( mamb > maxThreshold ) {
00717 index ++;
00718 _SwapPoints( theList, index, i );
00719 continue;
00720 }
00721 if ( mamb > minThreshold ) {
00722 am2 = _SquareDistance( theList[i], theSeg->extremity1, dim );
00723 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) ) - mamb*mamb < 0 ) {
00724 _SwapPoints( theList, i, l );
00725 i--; l--;
00726 continue;
00727 }
00728 if ( b < mamb ) b = mamb;
00729 continue;
00730 }
00731
00732 _SwapPoints( theList, i, l );
00733 i--; l--;
00734 }
00735
00736 } else {
00737
00738 for ( i=first; i<=l; i++ ) {
00739 mamb = _ScalarProduct( theList[i], theSeg->extremity1,
00740 theList[i], theSeg->extremity2, dim );
00741 if ( mamb > maxThreshold ) {
00742 index ++;
00743 _SwapPoints( theList, index, i );
00744 continue;
00745 }
00746 if ( mamb > medThreshold ) {
00747 if ( b < mamb ) b = mamb;
00748 continue;
00749 }
00750 if ( mamb > minThreshold ) {
00751 am2 = _SquareDistance( theList[i], theSeg->extremity1, dim );
00752 if ( 3.0 * ( am2 * ab2 - (am2 - mamb)*(am2 - mamb) )
00753 - (R2 - ab2 - mamb)*(R2 - ab2 - mamb) < 0 ) {
00754 _SwapPoints( theList, i, l );
00755 i--; l--;
00756 continue;
00757 }
00758 if ( b < mamb ) b = mamb;
00759 continue;
00760 }
00761
00762 _SwapPoints( theList, i, l );
00763 i--; l--;
00764 }
00765
00766 }
00767 *last = l;
00768 *bound = b;
00769 return( index );
00770
00771
00772
00773
00774 }
00775 return( -1 );
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 int _FarthestPointFromSphere( TypeSegment *theSeg,
00868 const double **theList,
00869 const int first,
00870 int *last,
00871 const int dim,
00872 const int _reduction_mode_ )
00873 {
00874 int i, l = (*last);
00875 int index = first - 1;
00876 double diff, maxdiff = 0.0;
00877
00878
00879 double threshold = -0.23205080756887729352 * theSeg->squareDiameter;
00880
00881 if ( l < first ) return( index );
00882
00883
00884 switch ( _reduction_mode_ ) {
00885
00886 case 0 :
00887
00888
00889
00890
00891 if ( dim == 2 ) {
00892 for ( i=first; i<=l; i++ ) {
00893 diff = _ScalarProduct2D( theList[i], theSeg->extremity1,
00894 theList[i], theSeg->extremity2 );
00895 if ( maxdiff < diff ) {
00896 index = i;
00897 maxdiff = diff;
00898 }
00899 }
00900 return( index );
00901 }
00902
00903 if ( dim == 3 ) {
00904 for ( i=first; i<=l; i++ ) {
00905 diff = _ScalarProduct3D( theList[i], theSeg->extremity1,
00906 theList[i], theSeg->extremity2 );
00907 if ( maxdiff < diff ) {
00908 index = i;
00909 maxdiff = diff;
00910 }
00911 }
00912 return( index );
00913 }
00914
00915 for ( i=first; i<=l; i++ ) {
00916 diff = _ScalarProduct( theList[i], theSeg->extremity1,
00917 theList[i], theSeg->extremity2, dim );
00918 if ( maxdiff < diff ) {
00919 index = i;
00920 maxdiff = diff;
00921 }
00922 }
00923 return( index );
00924
00925
00926
00927
00928 break;
00929
00930 default :
00931 case 1 :
00932
00933
00934
00935
00936
00937
00938
00939
00940 if ( dim == 2 ) {
00941 for ( i=first; i<=l; i++ ) {
00942 diff = _ScalarProduct2D( theList[i], theSeg->extremity1,
00943 theList[i], theSeg->extremity2 );
00944 if ( diff > maxdiff ) {
00945 index = i;
00946 maxdiff = diff;
00947 }
00948 else if ( diff <= threshold ) {
00949 _SwapPoints( theList, i, l );
00950 i --; l --;
00951 continue;
00952 }
00953 }
00954 *last = l;
00955 return( index );
00956 }
00957
00958
00959 if ( dim == 3 ) {
00960 for ( i=first; i<=l; i++ ) {
00961 diff = _ScalarProduct3D( theList[i], theSeg->extremity1,
00962 theList[i], theSeg->extremity2 );
00963 if ( maxdiff < diff ) {
00964 index = i;
00965 maxdiff = diff;
00966 }
00967 else if ( diff <= threshold ) {
00968 _SwapPoints( theList, i, l );
00969 i --; l --;
00970 continue;
00971 }
00972 }
00973 *last = l;
00974 return( index );
00975 }
00976
00977
00978 for ( i=first; i<=l; i++ ) {
00979 diff = _ScalarProduct( theList[i], theSeg->extremity1,
00980 theList[i], theSeg->extremity2, dim );
00981 if ( maxdiff < diff ) {
00982 index = i;
00983 maxdiff = diff;
00984 }
00985 else if ( diff <= threshold ) {
00986 _SwapPoints( theList, i, l );
00987 i --; l --;
00988 continue;
00989 }
00990 }
00991 *last = l;
00992 return( index );
00993
00994
00995
00996 }
00997
00998 return( -1 );
00999 }
01000
01001 double _MaximalSegmentInTwoLists( TypeSegment *theSeg,
01002 const int index1,
01003 const double **theList1,
01004 int *first1,
01005 int *last1,
01006 const double **theList2,
01007 int *first2,
01008 int *last2,
01009 int dim )
01010 {
01011
01012 int f1=*first1;
01013 int l1=*last1;
01014
01015 int i1 = index1;
01016
01017 int f2=*first2;
01018 int l2=*last2;
01019
01020 int i2;
01021
01022 const double *ref;
01023
01024 double d, dprevious;
01025
01026
01027 theSeg->extremity1 = (double*)NULL;
01028 theSeg->extremity2 = (double*)NULL;
01029 theSeg->squareDiameter = std::numeric_limits<double>::lowest();
01030
01031
01032 if ( *first1 < 0 || *last1 < 0 ) return( -1.0 );
01033 if ( *first1 > *last1 ) return( 0.0 );
01034 if ( *first2 < 0 || *last2 < 0 ) return( -1.0 );
01035 if ( *first2 > *last2 ) return( 0.0 );
01036 if ( *first2 > *last2 ) {
01037 l2 = *first2;
01038 f2 = *last2;
01039 }
01040 if ( index1 < f1 || index1 > l1 ) return( -1.0 );
01041
01042
01043 do {
01044
01045 dprevious = theSeg->squareDiameter;
01046
01047
01048
01049 ref = theList1[i1];
01050
01051
01052
01053
01054
01055 _SwapPoints( theList1, f1, i1 );
01056 f1 ++;
01057
01058
01059
01060 d = _MaximalDistanceFromPoint( &i2, ref, theList2, f2, l2, dim );
01061
01062
01063
01064 if ( d > theSeg->squareDiameter ) {
01065
01066 theSeg->extremity1 = ref;
01067 theSeg->extremity2 = theList2[i2];
01068 theSeg->squareDiameter = d;
01069
01070 if ( f1 <= l1 ) {
01071
01072 dprevious = theSeg->squareDiameter;
01073
01074
01075
01076 ref = theList2[i2];
01077
01078
01079
01080
01081
01082 _SwapPoints( theList2, f2, i2 );
01083 f2 ++;
01084
01085
01086
01087 d = _MaximalDistanceFromPoint( &i1, ref, theList1, f1, l1, dim );
01088
01089
01090
01091 if ( d > theSeg->squareDiameter ) {
01092
01093 theSeg->extremity1 = theList1[i1];
01094 theSeg->extremity2 = ref;
01095 theSeg->squareDiameter = d;
01096
01097 }
01098
01099 }
01100
01101 }
01102
01103
01104 } while( theSeg->squareDiameter > dprevious && f1 <= l1 && f2 <= l2 );
01105
01106
01107 *first1 = f1;
01108 *last1 = l1;
01109 *first2 = f2;
01110 *last2 = l2;
01111 return( theSeg->squareDiameter );
01112
01113 }
01114
01115 double _MaximalSegmentInOneList( TypeSegment *theSeg,
01116 const int index,
01117 const double **theList,
01118 int *first,
01119 int *last,
01120 const int dim )
01121 {
01122 int f=*first;
01123 int l=*last;
01124
01125 int i = index;
01126 const double *ref;
01127
01128 double d, dprevious;
01129
01130 theSeg->extremity1 = (double*)NULL;
01131 theSeg->extremity2 = (double*)NULL;
01132 theSeg->squareDiameter = std::numeric_limits<double>::lowest();
01133
01134
01135
01136 if ( *first < 0 || *last < 0 ) return( -1.0 );
01137 if ( *first > *last ) return( 0.0 );
01138 if ( index < f || index > l ) return( -1.0 );
01139 if ( f == l ) {
01140 theSeg->extremity1 = theList[i];
01141 theSeg->extremity2 = theList[i];
01142 return( 0.0 );
01143 }
01144
01145
01146
01147 do {
01148
01149 dprevious = theSeg->squareDiameter;
01150
01151
01152 ref = theList[i];
01153
01154
01155
01156
01157 _SwapPoints( theList, f, i );
01158 f ++;
01159
01160
01161
01162
01163 d = _MaximalDistanceFromPoint( &i, ref, theList, f, l, dim );
01164 if ( d > theSeg->squareDiameter ) {
01165 theSeg->extremity1 = ref;
01166 theSeg->extremity2 = theList[i];
01167 theSeg->squareDiameter = d;
01168 }
01169
01170
01171 } while ( theSeg->squareDiameter > dprevious && f <= l );
01172
01173 *first = f;
01174 *last = l;
01175 return( theSeg->squareDiameter );
01176 }
01177
01178 double _MaximalDistanceFromPoint( int *index,
01179 const double *ref,
01180 const double **theList,
01181 const int first,
01182 const int last,
01183 const int dim )
01184 {
01185 int f=first;
01186 int l=last;
01187 int i;
01188 double dmax, d;
01189
01190 *index = -1;
01191 if ( first < 0 || last < 0 ) return( -1.0 );
01192 if ( first > last ) return( 0.0 );
01193
01194
01195
01196 if ( dim == 2 ) {
01197
01198 dmax = _SquareDistance2D( theList[f], ref );
01199 *index = f;
01200
01201 for ( i=f+1; i<=l; i++ ) {
01202 d = _SquareDistance2D( theList[i], ref );
01203 if ( d > dmax ) {
01204 dmax = d;
01205 *index = i;
01206 }
01207 }
01208 return( dmax );
01209
01210 }
01211
01212 if ( dim == 3 ) {
01213
01214 dmax = _SquareDistance3D( theList[f], ref );
01215 *index = f;
01216
01217 for ( i=f+1; i<=l; i++ ) {
01218 d = _SquareDistance3D( theList[i], ref );
01219 if ( d > dmax ) {
01220 dmax = d;
01221 *index = i;
01222 }
01223 }
01224 return( dmax );
01225
01226 }
01227
01228
01229
01230
01231 dmax = _SquareDistance( theList[f], ref, dim );
01232 *index = f;
01233
01234 for ( i=f+1; i<=l; i++ ) {
01235 d = _SquareDistance( theList[i], ref, dim );
01236 if ( d > dmax ) {
01237 dmax = d;
01238 *index = i;
01239 }
01240 }
01241 return( dmax );
01242
01243 }
01244
01245
01246
01247
01248
01249 void _SwapPoints( const double **theList, const int i, const int j )
01250 {
01251 const double *tmp;
01252 tmp = theList[i];
01253 theList[i] = theList[j];
01254 theList[j] = tmp;
01255 }
01256
01257 static int _base_ = 100000000;
01258
01259 void _InitCounter( TypeCounter *c )
01260 {
01261 c->c1 = c->c2 = 0;
01262 }
01263 void _AddToCounter( TypeCounter *c, const int i )
01264 {
01265 c->c2 += i;
01266 while ( c->c2 >= _base_ ) {
01267 c->c2 -= _base_;
01268 c->c1 ++;
01269 }
01270 while ( c->c2 < 0 ) {
01271 c->c2 += _base_;
01272 c->c1 --;
01273 }
01274 }
01275 double _GetCounterAverage( TypeCounter *c, const int i )
01276 {
01277 return( (_base_ / (double)i ) * c->c1 + c->c2 / (double)i );
01278 }
01279
01280
01281 #ifdef _STATS_
01282 TypeCounter scalarProducts;
01283
01284 void _InitScalarProductCounter()
01285 {
01286 _InitCounter( &scalarProducts );
01287 }
01288 static void _IncScalarProductCounter()
01289 {
01290 _AddToCounter( &scalarProducts, 1 );
01291 }
01292 double _GetScalarProductAverage( int n )
01293 {
01294 return( _GetCounterAverage( &scalarProducts, n ) );
01295 }
01296 #endif
01297
01298
01299
01300
01301
01302
01303 double _SquareDistance( const double *a, const double *b, const int dim )
01304 {
01305 register int i;
01306 register double d = 0.0;
01307 register double ba;
01308 for ( i=0; i<dim; i++ ) {
01309 ba = b[i] - a[i];
01310 d += ba * ba;
01311 }
01312
01313 #ifdef _STATS_
01314 _IncScalarProductCounter();
01315 #endif
01316
01317 return( d );
01318 }
01319
01320
01321
01322
01323
01324 double _SquareDistance3D( const double *a, const double *b )
01325 {
01326
01327 #ifdef _STATS_
01328 _IncScalarProductCounter();
01329 #endif
01330
01331 return( (b[0]-a[0])*(b[0]-a[0]) +
01332 (b[1]-a[1])*(b[1]-a[1]) +
01333 (b[2]-a[2])*(b[2]-a[2]) );
01334 }
01335
01336
01337 double _SquareDistance2D( const double *a, const double *b )
01338 {
01339
01340 #ifdef _STATS_
01341 _IncScalarProductCounter();
01342 #endif
01343
01344 return( (b[0]-a[0])*(b[0]-a[0]) +
01345 (b[1]-a[1])*(b[1]-a[1]) );
01346 }
01347
01348
01349
01350
01351
01352
01353
01354 double _ScalarProduct( const double *a, const double *b,
01355 const double *c, const double *d, const int dim )
01356 {
01357 register int i;
01358 register double scalar = 0.0;
01359 register double ab, cd;
01360 for ( i=0; i<dim; i++ ) {
01361 ab = b[i] - a[i];
01362 cd = d[i] - c[i];
01363 scalar += ab * cd;
01364 }
01365
01366 #ifdef _STATS_
01367 _IncScalarProductCounter();
01368 #endif
01369
01370 return( scalar );
01371 }
01372
01373
01374
01375 double _ScalarProduct3D( const double *a, const double *b,
01376 const double *c, const double *d )
01377 {
01378
01379 #ifdef _STATS_
01380 _IncScalarProductCounter();
01381 #endif
01382
01383 return( (b[0]-a[0])*(d[0]-c[0]) +
01384 (b[1]-a[1])*(d[1]-c[1]) +
01385 (b[2]-a[2])*(d[2]-c[2]) );
01386 }
01387
01388 double _ScalarProduct2D( const double *a, const double *b,
01389 const double *c, const double *d )
01390 {
01391
01392 #ifdef _STATS_
01393 _IncScalarProductCounter();
01394 #endif
01395
01396 return( (b[0]-a[0])*(d[0]-c[0]) +
01397 (b[1]-a[1])*(d[1]-c[1]) );
01398 }
01399
01400 int _FindPointInList( const double **theList,
01401 const int first,
01402 const int last,
01403 double x0,
01404 double x1 )
01405 {
01406 int i, j=-1;
01407 double e=1e-5;
01408 for ( i=first; i<=last; i++ ) {
01409 if ( theList[i][0]-e < x0 && theList[i][0]+e > x0 &&
01410 theList[i][1]-e < x1 && theList[i][1]+e > x1 ) {
01411 if ( j == -1 ) {
01412 j = i;
01413 } else {
01414 fprintf( stderr, "found again at #%d\n", i );
01415 }
01416 }
01417 }
01418 return( j );
01419 }
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442 double _QuadraticDiameterInOneList( TypeSegment *theDiam,
01443 const double **theList,
01444 const int first,
01445 const int last,
01446 const int dim )
01447 {
01448 int i, j;
01449 double d;
01450
01451 theDiam->extremity1 = (double*)NULL;
01452 theDiam->extremity2 = (double*)NULL;
01453 theDiam->squareDiameter = std::numeric_limits<double>::lowest();
01454
01455 d = 0.0;
01456
01457 if ( dim == 2 ) {
01458
01459 for ( i=first; i<=last-1; i++ )
01460 for ( j=i+1; j<=last; j++ ) {
01461 d = _SquareDistance2D( theList[i], theList[j] );
01462 if ( d > theDiam->squareDiameter ) {
01463 theDiam->squareDiameter = d;
01464 theDiam->extremity1 = theList[i];
01465 theDiam->extremity2 = theList[j];
01466 }
01467 }
01468 return( theDiam->squareDiameter );
01469
01470 }
01471
01472
01473
01474 if ( dim == 3 ) {
01475
01476 for ( i=first; i<=last-1; i++ )
01477 for ( j=i+1; j<=last; j++ ) {
01478 d = _SquareDistance3D( theList[i], theList[j] );
01479 if ( d > theDiam->squareDiameter ) {
01480 theDiam->squareDiameter = d;
01481 theDiam->extremity1 = theList[i];
01482 theDiam->extremity2 = theList[j];
01483 }
01484 }
01485 return( theDiam->squareDiameter );
01486
01487 }
01488
01489
01490
01491 for ( i=first; i<=last-1; i++ )
01492 for ( j=i+1; j<=last; j++ ) {
01493 d = _SquareDistance( theList[i], theList[j], dim );
01494 if ( d > theDiam->squareDiameter ) {
01495 theDiam->squareDiameter = d;
01496 theDiam->extremity1 = theList[i];
01497 theDiam->extremity2 = theList[j];
01498 }
01499 }
01500
01501 return( theDiam->squareDiameter );
01502 }
01503
01504
01505
01506
01507
01508
01509
01510
01511 double _QuadraticDiameterInTwoLists( TypeSegment *theDiam,
01512 int *index1,
01513 int *index2,
01514 const double **theList1,
01515 const int first1,
01516 const int last1,
01517 const double **theList2,
01518 const int first2,
01519 const int last2,
01520 const int dim )
01521 {
01522 int i, j;
01523 double d;
01524
01525
01526
01527
01528
01529
01530
01531 if ( index1 != NULL && index2 != NULL ) {
01532 *index1 = first1-1;
01533 *index2 = first2-1;
01534 }
01535
01536 d = 0.0;
01537
01538 if ( dim == 2 ) {
01539
01540 for ( i=first1; i<=last1; i++ )
01541 for ( j=first2; j<=last2; j++ ) {
01542 d = _SquareDistance2D( theList1[i], theList2[j] );
01543 if ( d > theDiam->squareDiameter ) {
01544 theDiam->squareDiameter = d;
01545 theDiam->extremity1 = theList1[i];
01546 theDiam->extremity2 = theList2[j];
01547 if ( index1 != NULL && index2 != NULL ) {
01548 *index1 = i;
01549 *index2 = j;
01550 }
01551 }
01552 }
01553 return( theDiam->squareDiameter );
01554
01555 }
01556
01557
01558
01559 if ( dim == 3 ) {
01560
01561 for ( i=first1; i<=last1; i++ )
01562 for ( j=first2; j<=last2; j++ ) {
01563 d = _SquareDistance3D( theList1[i], theList2[j] );
01564 if ( d > theDiam->squareDiameter ) {
01565 theDiam->squareDiameter = d;
01566 theDiam->extremity1 = theList1[i];
01567 theDiam->extremity2 = theList2[j];
01568 if ( index1 != NULL && index2 != NULL ) {
01569 *index1 = i;
01570 *index2 = j;
01571 }
01572 }
01573 }
01574 return( theDiam->squareDiameter );
01575
01576 }
01577
01578
01579
01580 for ( i=first1; i<=last1; i++ )
01581 for ( j=first2; j<=last2; j++ ) {
01582 d = _SquareDistance( theList1[i], theList2[j], dim );
01583 if ( d > theDiam->squareDiameter ) {
01584 theDiam->squareDiameter = d;
01585 theDiam->extremity1 = theList1[i];
01586 theDiam->extremity2 = theList2[j];
01587 if ( index1 != NULL && index2 != NULL ) {
01588 *index1 = i;
01589 *index2 = j;
01590 }
01591 }
01592 }
01593
01594 return( theDiam->squareDiameter );
01595 }
01596
01597 }
01598 }