diff --git a/data/15Point.svg b/data/15Point.svg deleted file mode 100644 index 8016751..0000000 --- a/data/15Point.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/data/basic.dat b/data/basic.dat deleted file mode 100644 index 00c68d1..0000000 --- a/data/basic.dat +++ /dev/null @@ -1,8 +0,0 @@ -474.80999000000003 555.15656999999999 -474.80999000000003 530.87086999999997 -509.09570000000002 530.87086999999997 -543.38142000000005 530.87086999999997 -543.38142000000005 555.15656999999999 -543.38142000000005 579.44227000000001 -509.09570000000002 579.44227000000001 -474.80999000000003 579.44227000000001 \ No newline at end of file diff --git a/data/bird.dat b/data/bird.dat deleted file mode 100644 index caa9652..0000000 --- a/data/bird.dat +++ /dev/null @@ -1,275 +0,0 @@ -4.57998 4.03402 -4.06435 4.06435 -3.51839 4.21601 -3.09376 4.42832 -2.60846 4.57998 -2.09284 4.7013 -1.51655 4.82263 -0.909929 4.94395 -0.242648 5.06527 --0.30331 5.0956 --1.15258 5.12594 --1.72887 5.12594 --2.48714 5.12594 --2.85111 5.03494 --3.36674 5.30792 --3.70038 5.52024 --4.15534 5.9752 --4.7013 6.27851 --5.0956 6.61215 --5.73255 6.67281 --6.55149 6.73348 --6.88513 6.61215 --7.46142 6.36951 --7.88605 6.18752 --8.25003 5.91454 --8.64433 5.61123 --8.88698 5.30792 --9.06896 5.00461 --9.25095 4.88329 --9.94856 4.73163 --10.6462 4.64064 --11.1011 4.54965 --11.3741 4.42832 --11.5561 4.21601 --11.0101 4.21601 --10.1305 3.94303 --9.61492 3.73071 --9.15996 3.4274 --8.73532 3.00277 --8.34102 2.6388 --7.97705 2.36582 --7.61308 2.03218 --7.18844 1.45589 --6.79414 1.12225 --6.64248 0.788605 --6.36951 0.242648 --6.24818 -0.212317 --6.00553 -0.515627 --5.73255 -0.818936 --5.24726 -1.2739 --4.7923 -1.60754 --4.42832 -2.00184 --3.67005 -2.21416 --3.18475 -2.39615 --2.5478 -2.69946 --1.91085 -2.79045 --1.06158 -2.88144 --0.333641 -2.88144 -0.242648 -2.85111 -0.94026 -2.82078 -1.2739 -2.85111 -1.42556 -3.0331 -1.42556 -3.30608 -1.33456 -3.57905 -1.15258 -4.00369 -1.03125 -4.57998 -0.849267 -5.15627 -0.63695 -5.5809 -0.30331 -5.91454 -0.060662 -6.15719 --0.333641 -6.27851 --0.697612 -6.27851 --1.15258 -6.36951 --1.57721 -6.39984 --2.09284 -6.52116 --2.36582 -6.79414 --2.48714 -7.06712 --2.18383 -6.97612 --1.85019 -6.79414 --1.42556 -6.76381 --1.15258 -6.79414 --1.36489 -6.88513 --1.69853 -6.97612 --1.97151 -7.12778 --2.12317 -7.37043 --2.27482 -7.64341 --2.39615 -7.91639 --2.36582 -8.21969 --2.03218 -7.85572 --1.81986 -7.7344 --1.57721 -7.67374 --1.36489 -7.49175 --1.21324 -7.40076 --0.849267 -7.2491 --0.60662 -7.12778 --0.242648 -6.91546 -0.030331 -6.70315 -0.363972 -6.4605 -0.242648 -6.61215 -0.152837 -6.72007 --0.092855 -6.88818 --0.506653 -7.15974 --0.765276 -7.31491 --1.01097 -7.41836 --1.16614 -7.5606 --1.32132 -7.71577 --1.45063 -7.81922 --1.50235 -8.06492 --1.50235 -8.29768 --1.46356 -8.53044 --1.38597 -8.29768 --1.28252 -8.05199 --1.14028 -7.87095 --0.985106 -7.84509 --0.817001 -7.84509 --0.623033 -7.70284 --0.390272 -7.52181 --0.105787 -7.31491 -0.178699 -7.06922 -0.489047 -6.84939 -0.670083 -6.66835 -0.928707 -6.47438 -1.16147 -6.33214 -1.47182 -6.13817 -1.82096 -5.91834 -2.04079 -5.84076 -2.15717 -5.71144 -2.18303 -5.45282 -2.06665 -5.28472 -1.87268 -5.3623 -1.49768 -5.63386 -1.22612 -5.81489 -1.03216 -5.91834 -0.876982 -5.95714 -0.954569 -5.80196 -1.00629 -5.60799 -1.16147 -5.29765 -1.3425 -4.9873 -1.45888 -4.65109 -1.47182 -4.4054 -1.73044 -3.95281 -1.84682 -3.6166 -1.98906 -3.30625 -2.14424 -2.95711 -2.26062 -2.75021 -2.42872 -2.59503 -2.63562 -2.50452 -2.98476 -2.51745 -3.12701 -2.71141 -3.06235 -3.09935 -2.9589 -3.4097 -2.86838 -3.75884 -2.79079 -4.12091 -2.70028 -4.43126 -2.55803 -4.75454 -2.48045 -5.03902 -2.3382 -5.37523 -2.29941 -5.59506 -2.23475 -5.90541 -2.11837 -6.21576 -1.7951 -6.65542 -1.39423 -7.05628 -1.09681 -7.26318 -0.838188 -7.37956 -0.41146 -7.49594 --0.002337 -7.62526 --0.416135 -7.7675 --0.687689 -8.05199 --0.907519 -8.40113 --0.70062 -8.19423 --0.312685 -8.05199 --0.015268 -7.89681 -0.217493 -7.89681 -0.243355 -7.90974 -0.023525 -8.1425 --0.157511 -8.25888 --0.403203 -8.43992 --0.648896 -8.75027 --0.778207 -8.90544 --0.881657 -9.18993 --0.80407 -9.60372 --0.597171 -9.177 --0.14458 -8.9701 -0.269217 -8.62096 -0.695946 -8.28475 -1.13561 -8.00026 -1.52354 -7.62526 -1.82096 -7.26318 -1.95027 -7.09508 -1.9632 -7.15974 -1.66578 -7.58646 -1.45888 -7.84509 -1.13561 -8.20716 -0.760601 -8.65975 -0.450253 -8.99596 -0.269217 -9.28045 -0.126974 -9.65545 -0.19163 -10.2761 -0.333873 -9.84942 -0.63129 -9.68131 -0.980431 -9.26751 -1.26492 -8.72441 -1.60113 -8.31061 -1.98906 -7.7675 -2.36407 -7.34077 -2.79079 -7.00456 -3.13994 -6.7718 -3.68304 -6.46145 -4.14857 -6.33214 -4.7434 -6.09938 -5.19599 -6.13817 -4.85978 -5.87955 -4.29081 -5.76317 -3.77356 -5.81489 -3.34683 -6.07352 -2.77786 -6.47438 -2.41579 -6.60369 -2.41579 -6.28042 -2.59683 -5.84076 -2.79079 -5.42696 -2.99769 -4.90971 -3.25632 -4.30195 -3.50201 -3.52608 -3.83822 -2.63383 -4.07098 -2.40107 -4.39426 -2.28469 -4.79512 -2.23296 -4.54943 -2.02606 -4.49771 -1.6252 -4.54943 -1.50882 -4.91151 -1.50882 -5.54513 -1.45709 -6.12704 -1.39244 -6.85118 -1.32778 -7.44601 -1.14674 -7.85981 -0.78467 -7.79516 -0.409667 -7.49774 -0.151043 -7.84688 0.042924 -8.23481 0.314479 -8.64861 0.702414 -8.70034 1.09035 -8.41585 1.42656 -8.11843 1.62053 -8.3512 2.06019 -8.53223 2.38347 -8.67447 2.74554 -8.66154 3.22399 -8.80379 3.87055 -8.90724 4.36193 -9.1012 4.85332 -9.43741 5.40936 -9.90293 6.04298 -10.3167 6.58609 -10.7047 7.3749 -10.9374 7.96973 -11.1573 8.40939 -11.1573 8.84905 -10.9374 9.05595 -10.6659 9.28871 -10.3426 9.37922 -9.99345 9.34043 -9.63138 8.97836 -9.20465 8.48697 -8.86844 8.1249 -8.50637 7.72404 -8.17016 7.28438 -7.74343 6.88351 -7.43308 6.5473 -7.16153 6.1723 -6.70894 5.71971 -6.20462 5.25418 -5.72617 4.80159 -5.13134 4.41366 -4.87271 4.16797 \ No newline at end of file diff --git a/data/dude.dat b/data/dude.dat deleted file mode 100644 index 7e43f9c..0000000 --- a/data/dude.dat +++ /dev/null @@ -1,94 +0,0 @@ -280.35714 648.79075 -286.78571 662.8979 -263.28607 661.17871 -262.31092 671.41548 -250.53571 677.00504 -250.53571 683.43361 -256.42857 685.21933 -297.14286 669.50504 -289.28571 649.50504 -285 631.6479 -285 608.79075 -292.85714 585.21932 -306.42857 563.79075 -323.57143 548.79075 -339.28571 545.21932 -357.85714 547.36218 -375 550.21932 -391.42857 568.07647 -404.28571 588.79075 -413.57143 612.36218 -417.14286 628.07647 -438.57143 619.1479 -438.03572 618.96932 -437.5 609.50504 -426.96429 609.86218 -424.64286 615.57647 -419.82143 615.04075 -420.35714 605.04075 -428.39286 598.43361 -437.85714 599.68361 -443.57143 613.79075 -450.71429 610.21933 -431.42857 575.21932 -405.71429 550.21932 -372.85714 534.50504 -349.28571 531.6479 -346.42857 521.6479 -346.42857 511.6479 -350.71429 496.6479 -367.85714 476.6479 -377.14286 460.93361 -385.71429 445.21932 -388.57143 404.50504 -360 352.36218 -337.14286 325.93361 -330.71429 334.50504 -347.14286 354.50504 -337.85714 370.21932 -333.57143 359.50504 -319.28571 353.07647 -312.85714 366.6479 -350.71429 387.36218 -368.57143 408.07647 -375.71429 431.6479 -372.14286 454.50504 -366.42857 462.36218 -352.85714 462.36218 -336.42857 456.6479 -332.85714 438.79075 -338.57143 423.79075 -338.57143 411.6479 -327.85714 405.93361 -320.71429 407.36218 -315.71429 423.07647 -314.28571 440.21932 -325 447.71932 -324.82143 460.93361 -317.85714 470.57647 -304.28571 483.79075 -287.14286 491.29075 -263.03571 498.61218 -251.60714 503.07647 -251.25 533.61218 -260.71429 533.61218 -272.85714 528.43361 -286.07143 518.61218 -297.32143 508.25504 -297.85714 507.36218 -298.39286 506.46932 -307.14286 496.6479 -312.67857 491.6479 -317.32143 503.07647 -322.5 514.1479 -325.53571 521.11218 -327.14286 525.75504 -326.96429 535.04075 -311.78571 540.04075 -291.07143 552.71932 -274.82143 568.43361 -259.10714 592.8979 -254.28571 604.50504 -251.07143 621.11218 -250.53571 649.1479 -268.1955 654.36208 diff --git a/data/dude.svg b/data/dude.svg deleted file mode 100644 index cdf867f..0000000 --- a/data/dude.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/data/i.18 b/data/i.18 deleted file mode 100644 index 79ae282..0000000 --- a/data/i.18 +++ /dev/null @@ -1,18 +0,0 @@ -0 0 -10 7 -12 3 -20 8 -13 17 -10 12 -12 14 -14 9 -8 10 -6 14 -10 15 -7 18 -0 16 -1 13 -3 15 -5 8 --2 9 -5 5 diff --git a/data/i.snake b/data/i.snake deleted file mode 100644 index 94633e7..0000000 --- a/data/i.snake +++ /dev/null @@ -1,12 +0,0 @@ -10 0 -20 10 -30 0 -40 10 -50 0 -50 10 -40 20 -30 10 -20 20 -10 10 -0 20 -0 10 diff --git a/data/i.sq b/data/i.sq deleted file mode 100644 index 1631e41..0000000 --- a/data/i.sq +++ /dev/null @@ -1,4 +0,0 @@ -0 0 -10 0 -10 10 -0 10 diff --git a/data/i.tri b/data/i.tri deleted file mode 100644 index 0f5a288..0000000 --- a/data/i.tri +++ /dev/null @@ -1,3 +0,0 @@ -0 0 -1 0 -1 1 diff --git a/data/nazca_heron.dat b/data/nazca_heron.dat deleted file mode 100644 index 14aebf8..0000000 --- a/data/nazca_heron.dat +++ /dev/null @@ -1,1036 +0,0 @@ --91.726 10.4022 --92.5616 10.385 --93.0053 10.4193 --93.8429 10.4444 --94.4002 10.3881 --95.1773 10.4322 --95.731 10.328 --96.0661 10.0034 --95.7371 9.52215 --95.0108 9.51904 --93.8987 9.40352 --93.063 9.41048 --92.1174 9.36365 --91.1689 9.32841 --90.1664 9.32695 --89.2738 9.29848 --87.9935 9.21778 --87.1011 9.24003 --85.9323 9.16578 --84.818 9.2136 --83.8152 9.2263 --82.3111 9.25894 --81.2523 9.21521 --80.3055 9.26966 --79.1913 9.27179 --78.3561 9.26927 --77.4071 9.2506 --76.2938 9.15212 --75.2359 9.21265 --74.2889 9.23221 --73.2304 9.22176 --72.3344 9.24597 --71.3911 9.06377 --70.7225 9.00533 --69.8321 8.87212 --68.5508 8.90126 --67.2126 8.90584 --66.2109 8.83119 --65.1525 8.76935 --64.2054 8.77328 --62.9784 8.69629 --62.0884 8.7899 --61.1999 8.81082 --60.4738 8.81708 --59.6372 8.77889 --58.3559 8.77041 --57.8008 8.75645 --57.2974 8.71659 --56.6289 8.69558 --55.7933 8.71756 --55.1804 8.7228 --54.4562 8.71456 --53.3976 8.71721 --52.2278 8.78652 --51.4479 8.73714 --50.4451 8.74938 --49.8323 8.77075 --48.6067 8.78685 --47.7153 8.78148 --46.9345 8.79131 --45.8212 8.72036 --44.9864 8.73653 --43.76 8.7899 --43.2029 8.80459 --42.5953 8.82626 --42.0346 8.81404 --41.4759 8.75151 --40.7516 8.71843 --40.1388 8.78394 --39.5817 8.75781 --39.1361 8.75758 --38.6347 8.80655 --38.2447 8.77854 --37.8547 8.74123 --37.4091 8.7923 --35.9611 8.78602 --34.6793 8.78076 --33.8436 8.83903 --32.8966 8.83963 --32.0052 8.8087 --31.0024 8.86909 --29.9997 8.8264 --29.1083 8.82878 --27.7705 8.83849 --26.5457 8.72773 --25.4873 8.7165 --24.2616 8.6655 --23.0892 8.68424 --22.1449 8.54477 --20.8074 8.50105 --19.5257 8.45263 --17.9667 8.37676 --16.6851 8.31799 --15.5706 8.3359 --14.401 8.27044 --13.2307 8.27746 --12.5648 8.24932 --11.7826 8.30542 --11.225 8.26741 --10.6119 8.33761 --9.94418 8.2737 --9.10957 8.29055 --8.16166 8.32522 --7.15627 8.31888 --6.10021 8.19418 --5.04173 8.20764 --4.20608 8.21455 --3.25902 8.21726 --2.09019 8.14631 --1.30858 8.09495 --0.306399 8.16141 -0.528273 8.19199 -1.97994 8.12994 -2.75763 8.20323 -3.48095 8.19986 -4.54034 8.18316 -5.26597 8.14464 -5.93308 8.20355 -6.37876 8.23306 -6.93779 8.20172 -7.38503 8.28515 -7.75928 8.14925 -8.10818 7.83366 -8.55309 7.68152 -9.27282 7.59373 -10.1085 7.35329 -10.6702 7.35345 -11.5114 7.20388 -12.5089 7.36493 -13.4027 7.4728 -14.412 7.6901 -15.1803 8.05105 -15.6266 8.26723 -16.2416 8.29494 -17.0758 8.37201 -17.9672 8.45068 -18.6906 8.3527 -19.4689 8.36621 -20.0833 8.32903 -20.8076 8.36605 -21.5349 8.39958 -22.811 8.30214 -23.5936 8.32996 -24.2817 8.11023 -24.3617 7.60334 -24.4628 6.99157 -24.4059 6.20837 -24.5479 5.43455 -24.7617 4.81808 -25.0482 4.37841 -25.4039 3.83047 -25.9341 3.55091 -26.5429 3.48577 -27.1405 3.94951 -27.7711 4.42902 -28.3433 5.30396 -29.0083 5.9264 -29.3964 6.59346 -30.0334 7.39695 -30.4568 7.93096 -30.9385 8.5706 -31.4443 9.3344 -31.9062 9.83899 -32.3178 9.99556 -32.4543 9.44194 -32.3424 8.99712 -32.3298 8.3286 -32.2872 7.66008 -32.3614 7.04572 -32.2586 6.26963 -32.1964 5.65849 -32.1029 4.76416 -32.0489 3.98324 -32.0854 3.31228 -31.9712 2.75763 -32.0396 2.13545 -31.8344 1.53202 -31.8289 0.861208 -31.99 0.183618 -32.3457 -0.243851 -32.8982 -0.739612 -33.7837 -0.849395 -34.3622 -0.710696 -34.8876 -0.0191316 -35.4023 0.808785 -35.7456 1.19234 -36.2095 1.94174 -36.8011 2.75484 -37.2693 3.52304 -37.7639 4.47142 -38.2574 5.25764 -38.5964 5.86575 -39.0468 6.53111 -39.4802 7.20908 -39.8636 7.93611 -40.3677 8.68935 -40.853 9.50473 -41.3001 10.2266 -41.5896 10.8341 -41.8697 11.2788 -42.1444 11.7269 -42.4414 12.3274 -42.8817 13.0026 -43.044 13.3927 -43.2547 13.7354 -43.8157 14.4808 -44.21 14.4567 -44.2384 13.7881 -44.214 13.1202 -44.2478 12.3397 -44.2545 11.504 -44.2471 10.2762 -44.383 9.55421 -44.3819 8.8306 -44.4857 7.99434 -44.4374 7.1038 -44.4823 6.49018 -44.5055 5.54178 -44.3968 4.65176 -44.4035 3.87539 -44.3112 3.09147 -44.3678 2.31195 -44.3634 1.64156 -44.4741 1.08215 -44.7443 0.405587 -45.098 -0.0812431 -45.5916 -0.319965 -46.0404 -0.518244 -47.0404 -0.187042 -47.6198 0.241597 -48.0225 1.04872 -48.4879 1.70359 -49.0113 2.52644 -49.4565 3.30864 -49.7829 4.08959 -50.2298 4.64717 -50.7013 5.35933 -50.968 6.06294 -51.3782 6.77734 -51.8168 7.50498 -52.2817 8.27353 -52.5085 8.88449 -52.9297 9.67783 -53.2782 10.2838 -53.7366 10.9445 -54.1325 11.6654 -54.43 12.1549 -54.74 12.7268 -54.9842 13.2537 -55.3914 13.7539 -55.9159 14.019 -56.1591 13.621 -56.1814 12.7857 -56.0542 11.8895 -55.901 10.9481 -55.755 10.1629 -55.6441 9.16009 -55.4555 8.44064 -55.3158 7.48927 -55.1979 6.76738 -55.1458 6.04168 -55.0153 5.20856 -54.9225 4.47831 -54.6817 3.75997 -54.4404 2.76892 -54.3443 1.69915 -54.3354 0.809666 -54.1511 -0.0300711 -54.2166 -0.702496 -54.453 -1.31046 -54.6851 -1.85943 -55.1255 -2.25343 -55.7401 -2.43474 -56.4817 -2.28494 -57.1939 -1.76082 -57.67 -1.0781 -58.1661 -0.0158294 -58.7044 0.911084 -59.1398 1.69647 -59.5985 2.35776 -59.9523 3.04503 -60.2915 3.7707 -60.7648 4.36495 -61.1845 5.10498 -61.5282 5.65631 -61.9625 6.44572 -62.3804 6.92578 -62.7068 7.38979 -63.1888 7.02434 -63.7594 6.71273 -64.4182 5.92176 -64.9326 5.49007 -65.436 4.93653 -65.9846 4.48258 -66.3835 3.82101 -66.8552 3.23917 -67.3884 2.6537 -67.8008 2.17994 -68.2584 1.64344 -68.2649 0.417823 -68.2525 -0.137759 -68.212 -0.863123 -68.2058 -1.53202 -68.1769 -2.19838 -68.2882 -3.03763 -68.1923 -3.65085 -68.2978 -4.37321 -68.3021 -5.31814 -68.2969 -6.10242 -68.4 -6.88111 -68.3005 -7.82472 -68.273 -8.44002 -68.2464 -9.2692 -68.1829 -9.71818 -68.245 -10.5034 -68.3322 -11.2255 -68.3078 -11.8903 -68.2012 -12.5096 -68.3418 -13.1022 -68.6065 -13.3261 -69.0974 -13.3425 -69.0796 -12.6196 -69.0225 -11.5006 -69.1975 -10.0556 -69.2256 -8.9414 -69.243 -7.60627 -69.3237 -6.21134 -69.4118 -4.87177 -69.2502 -3.87182 -69.2618 -2.97959 -69.3274 -2.14482 -69.3415 -1.36489 -69.3206 -0.686317 -69.6114 -0.427229 -70.0984 -0.312499 -70.4035 -0.864603 -70.2948 -1.58221 -70.2543 -2.36766 -70.2135 -3.09189 -70.2426 -3.81611 -70.1699 -4.54469 -70.2999 -5.2107 -70.2593 -5.87737 -70.1916 -6.43108 -70.1723 -6.93454 -70.244 -7.43724 -70.2816 -8.16147 -70.289 -8.88495 -70.3531 -9.72134 -70.3477 -10.3873 -70.4535 -11.0022 -70.4808 -11.9497 -70.4864 -12.6171 -70.4493 -13.34 -70.6577 -13.7504 -71.1761 -14.0215 -71.6078 -13.6693 -71.7849 -12.7296 -71.7493 -11.1698 -71.7383 -10.222 -71.6867 -9.21995 -71.5978 -8.10296 -71.6945 -6.65731 -71.724 -5.6547 -71.6909 -4.93167 -71.7255 -4.0947 -71.6829 -3.09189 -71.6556 -2.31361 -71.5993 -1.80799 -71.7354 -1.15126 -72.1227 -0.732545 -72.5957 -0.924082 -72.7269 -1.42072 -72.798 -2.41973 -72.955 -3.03618 -72.9628 -3.64899 -72.95 -4.20608 -72.939 -4.93373 -73.1754 -5.7659 -73.2306 -6.60159 -73.258 -7.4394 -73.3313 -8.16212 -73.4053 -9.05141 -73.5125 -9.66491 -73.582 -10.2253 -73.6984 -11.0503 -73.9074 -11.6638 -74.2887 -12.1152 -74.8254 -12.0555 -75.0308 -11.4474 -74.9288 -10.3949 -74.7818 -9.44347 -74.6863 -8.04964 -74.5524 -7.05342 -74.5059 -5.76663 -74.406 -4.81738 -74.1716 -3.98324 -74.1828 -3.14729 -74.1627 -2.19507 -73.9711 -1.31592 -74.2954 -1.13944 -74.4945 -1.70344 -74.7325 -2.59075 -74.8428 -3.48254 -75.0145 -4.26162 -75.1478 -5.1454 -75.3825 -5.99195 -75.5103 -6.71359 -75.6344 -7.54683 -75.7996 -8.32736 -75.9504 -9.2252 -76.3494 -9.94925 -76.7611 -10.013 -77.0247 -9.55421 -77.0168 -8.60758 -76.7722 -7.66401 -76.5674 -6.32409 -76.3879 -5.43546 -76.1592 -4.37618 -76.079 -3.48081 -75.9239 -2.71101 -75.7774 -2.03729 -75.699 -1.59737 -75.9528 -1.05432 -76.6689 -0.939149 -77.1612 -1.32968 -77.4792 -1.61957 -77.9039 -1.91182 -78.1904 -1.77006 -78.6284 -1.71267 -79.0308 -1.85639 -79.5234 -2.19157 -79.7474 -2.14619 -80.2003 -2.47286 -80.416 -2.7096 -80.9208 -2.76515 -81.2445 -2.63541 -81.4789 -2.47298 -81.858 -2.71375 -82.3006 -3.00137 -82.6434 -3.14951 -82.8334 -3.30639 -82.9618 -3.5857 -83.0542 -4.13459 -83.3045 -4.51251 -83.4828 -4.53942 -83.6902 -5.01666 -84.1795 -5.22944 -84.433 -5.47731 -84.8724 -5.69724 -85.44 -5.65169 -85.2045 -4.93327 -84.9319 -4.59458 -84.5801 -4.0562 -85.0434 -4.41845 -85.4846 -4.5517 -85.822 -4.58297 -86.4291 -4.66072 -86.8641 -4.8989 -87.3249 -5.1661 -87.7599 -5.17183 -88.1596 -5.38038 -88.8845 -5.54301 -89.0758 -5.03874 -88.9908 -4.60685 -88.4392 -4.31739 -87.9944 -3.92687 -87.8263 -3.73325 -87.3787 -3.69144 -86.9907 -3.74579 -86.667 -3.74799 -86.307 -3.39915 -86.1521 -3.29102 -85.5422 -3.20372 -84.9936 -3.25056 -84.8131 -3.09682 -84.6518 -2.92498 -84.7139 -2.70778 -84.9344 -2.41951 -84.5395 -1.91678 -84.1568 -1.92933 -83.8164 -2.26671 -83.3204 -2.25906 -82.8592 -2.28033 -82.4168 -2.10331 -81.8816 -1.84037 -81.4293 -1.57093 -81.032 -1.35101 -80.3612 -1.25898 -79.9668 -1.28969 -79.5208 -1.24133 -79.0219 -1.15593 -78.3544 -1.03266 -77.9372 -0.724926 -77.6381 -0.532779 -78.1321 -0.412019 -79.022 -0.334834 -79.7365 -0.403715 -80.53 -0.579743 -81.084 -0.760943 -81.8071 -0.895225 -82.4782 -0.914448 -82.9781 -0.930945 -83.4276 -0.936112 -84.3706 -1.03896 -85.2088 -1.1944 -85.9289 -1.39795 -87.0464 -1.4622 -87.9377 -1.49596 -88.659 -1.51403 -90.0546 -1.58832 -90.7826 -1.72732 -91.6118 -1.8804 -92.4502 -2.01859 -93.3968 -2.0376 -94.4012 -2.15891 -95.1315 -2.09807 -95.6052 -1.6493 -95.6245 -0.920633 -95.0142 -0.412069 -94.0101 -0.144715 -93.1187 -0.189432 -92.1155 -0.184855 -90.8904 -0.243803 -89.5533 -0.237599 -88.6615 -0.236242 -87.1578 -0.303836 -85.8783 -0.270527 -84.7623 -0.250566 -83.5943 -0.129718 -82.7553 0.0179645 -81.1995 0.260974 -80.5318 0.411907 -80.9183 0.658629 -82.1999 0.635839 -84.0376 0.771737 -86.0993 0.803398 -88.1648 0.84411 -89.609 0.65952 -91.2238 0.624693 -92.3389 0.58028 -94.4558 0.66607 -95.2629 0.660988 -95.5713 1.03034 -95.7391 1.81258 -95.4034 2.13092 -94.1247 2.06277 -92.2822 1.89953 -90.2776 1.75379 -88.6628 1.83331 -87.0464 1.86452 -85.2636 1.86765 -83.8709 1.82 -82.2554 1.79107 -81.0865 1.79007 -80.1157 1.74386 -80.1334 1.93887 -81.0811 2.23192 -82.7003 2.42892 -84.5395 2.65818 -86.0436 2.63221 -87.6047 2.63459 -88.7183 2.74889 -90.334 2.88772 -91.8931 2.83109 -93.0628 2.81122 -94.1236 2.69508 -94.8341 2.93287 -95.2499 3.48754 -95.0085 4.03008 -94.3443 4.37434 -92.8445 4.17146 -91.5055 4.02086 -90.1646 3.8803 -88.9421 3.6319 -87.1005 3.49 -85.9879 3.25387 -85.0421 3.24464 -83.7595 3.20743 -82.9798 3.14365 -81.8622 3.11751 -80.976 2.96988 -81.0885 3.47024 -81.9378 3.6489 -82.4922 3.83974 -83.3647 4.27166 -84.0266 4.62188 -84.5386 4.82064 -84.9745 5.02323 -85.3698 4.81152 -85.7651 4.6058 -86.4328 4.548 -86.9687 4.59919 -87.0659 4.99771 -86.8618 5.24124 -86.6658 5.44818 -86.2668 5.6535 -87.1019 5.87851 -87.7698 5.99097 -88.3791 6.22568 -89.1112 6.4213 -89.7168 6.61037 -90.3558 6.91892 -90.7855 7.21441 -90.7737 7.54215 -90.5004 7.77089 -89.9933 7.79614 -89.2749 7.60375 -88.4356 7.44428 -87.8883 7.17135 -87.6597 7.26648 -87.2029 7.22145 -87.0047 6.8102 -86.7121 6.82344 -86.3262 6.82444 -86.3146 7.16477 -86.553 7.43624 -86.6073 7.89827 -86.212 8.04484 -85.7741 7.92294 -85.3727 7.71698 -85.159 7.26678 -84.9196 6.82769 -84.8213 6.48738 -84.4684 6.12775 -83.9911 5.79129 -83.5915 5.71275 -83.1381 5.56378 -82.4792 5.26258 -81.7937 4.96558 -81.1962 4.65765 -80.7362 4.6232 -80.4787 4.909 -80.08 4.82191 -79.4998 4.23189 -78.8931 3.72655 -78.3428 3.20188 -78.3092 3.71576 -77.9599 3.9784 -77.719 4.30016 -78.0395 4.91762 -78.4051 5.49132 -78.9135 6.40463 -79.4112 7.32762 -79.9172 8.16058 -80.4247 9.10461 -80.7546 9.775 -81.0854 10.3341 -81.5764 11.0636 -81.8685 11.6162 -81.754 12.1079 -81.3082 12.1171 -81.0363 11.8892 -80.568 11.2937 -80.1876 10.7835 -79.7582 9.99418 -79.3481 9.33988 -78.8698 8.71184 -78.3571 7.77085 -78.0088 7.05571 -77.5734 6.38028 -77.1178 5.71761 -76.8005 5.15005 -76.337 4.49448 -75.9919 4.03294 -75.994 4.26179 -75.9583 4.9314 -76.3466 5.60066 -76.8133 6.4246 -77.2997 7.32439 -77.9281 8.37226 -78.6042 9.37164 -79.0863 10.2193 -79.4958 10.9289 -79.856 11.5059 -80.1477 12.0564 -80.5155 12.8522 -80.861 13.2316 -81.1485 14.0724 -80.7678 14.5459 -80.3209 14.2254 -79.9206 13.6464 -79.6606 13.0853 -79.2478 12.395 -78.8736 11.7173 -78.4521 11.0659 -78.0784 10.2776 -77.7548 9.71539 -77.29 8.8348 -76.9343 8.3413 -76.7456 7.82355 -76.4154 7.32071 -75.9858 6.4719 -75.4055 5.70854 -74.8422 4.93221 -74.6119 4.49262 -74.3462 4.09592 -74.1215 4.37322 -74.1782 5.09694 -74.8469 5.98837 -75.4801 7.25591 -76.0283 8.0968 -76.7103 9.12227 -77.398 10.5616 -77.7939 11.4511 -78.3011 12.2833 -78.8654 13.1148 -79.2539 13.7846 -79.623 14.5733 -79.9541 15.4692 -80.3716 16.2507 -80.5987 16.9298 -80.0747 17.2511 -79.5869 16.7935 -79.1336 15.9618 -78.7511 15.1781 -78.3425 14.4076 -77.8659 13.3927 -77.4296 12.4389 -76.7817 11.4001 -76.3303 10.5669 -76.0301 9.87661 -75.4467 9.22674 -74.962 8.32609 -74.622 7.71632 -74.2949 6.98872 -73.7711 5.93905 -73.5375 5.33381 -73.2448 4.64053 -72.84 4.14617 -72.2613 4.19979 -72.1516 4.60385 -72.4467 5.32227 -72.8275 6.05278 -73.3687 6.80996 -74.1322 8.26793 -74.6116 9.3374 -75.1627 10.3982 -75.6426 11.3286 -76.0586 12.2348 -76.3405 12.7905 -76.8518 13.7323 -77.198 14.5048 -77.7446 15.4027 -78.1249 16.0761 -78.3535 16.5196 -78.687 16.9633 -78.637 17.4934 -78.067 17.5349 -77.669 17.2531 -77.3505 16.6867 -77.0095 16.1879 -76.6357 15.3447 -76.179 14.4034 -75.8572 13.8396 -75.458 13.0644 -74.8572 11.9994 -74.4823 11.2672 -74.0028 10.4494 -73.6473 9.65219 -73.242 8.87957 -72.7264 7.93995 -72.3241 7.16613 -71.8701 6.28093 -71.5224 5.58931 -71.194 4.91632 -70.6833 4.02852 -70.1796 3.41292 -69.7207 2.8571 -69.2136 2.86331 -68.7805 3.32243 -68.1988 3.80251 -67.6737 4.55604 -67.0607 5.11157 -66.5602 5.61566 -66.0439 6.04454 -65.542 6.65693 -65.0516 7.28061 -64.4886 7.83231 -63.8682 8.38166 -63.4806 8.82701 -62.6509 8.98197 -61.8701 8.71545 -61.5024 8.14539 -61.1667 7.58665 -60.7729 7.03534 -60.4889 6.53788 -60.1274 5.88575 -59.7446 5.45344 -59.5827 4.81796 -59.1301 4.26463 -58.8581 3.70411 -58.481 3.13902 -58.1724 2.71238 -57.7765 2.10247 -57.4722 1.52727 -57.0016 0.817253 -56.6784 0.198728 -56.354 -0.372287 -55.7403 -0.584321 -55.6175 -0.083565 -55.6389 0.638398 -55.8152 1.58658 -55.8485 2.64634 -56.0662 3.48261 -56.2021 4.3124 -56.5438 5.76862 -56.6148 7.00231 -56.7995 7.71535 -56.9572 8.59928 -57.0697 9.66596 -57.1411 10.4998 -57.2485 11.2812 -57.2209 12.0068 -57.2864 12.8427 -57.4071 13.621 -57.4292 14.4641 -57.1339 15.0174 -56.756 15.5683 -55.8035 15.7749 -55.1888 15.45 -54.702 14.9986 -54.3267 14.5244 -53.8733 13.8576 -53.4584 13.0049 -53.0047 12.3416 -52.5121 11.5011 -52.213 10.9564 -51.9035 10.2931 -51.5297 9.9067 -51.116 9.16314 -50.8362 8.55092 -50.4922 7.83421 -50.0078 7.21066 -49.7895 6.70805 -49.5116 5.97696 -49.1128 5.5406 -48.714 4.82213 -48.2439 4.27275 -47.9923 3.53879 -47.4039 2.74948 -47.1212 1.96748 -46.7692 1.35872 -46.3782 1.30907 -45.9053 1.69915 -45.869 2.64621 -45.9339 3.87182 -45.9591 5.37443 -46.0595 6.32305 -45.9919 7.60484 -45.8376 8.88829 -45.6288 9.94298 -45.6099 11.1148 -45.5345 12.0054 -45.5154 12.8441 -45.6385 13.8427 -45.5997 14.5682 -45.5452 15.6848 -44.9829 16.225 -44.0949 16.4052 -43.265 15.9555 -42.7019 15.2921 -42.1312 14.4089 -41.6672 13.5517 -41.1422 12.6737 -40.8033 12.008 -40.2677 11.2383 -40.065 10.5723 -39.4596 9.8392 -38.9891 8.98232 -38.3485 8.16589 -37.959 7.49736 -37.5209 6.76843 -37.0109 6.16027 -36.5893 5.31344 -36.0748 4.14867 -35.5462 3.32695 -35.0692 2.31194 -34.7339 1.6445 -34.1748 1.06472 -33.7977 1.14943 -33.2575 1.81321 -33.45 3.03618 -33.4054 4.20571 -33.4258 5.32202 -33.5421 6.21163 -33.5726 7.65692 -33.5749 8.77428 -33.5748 9.55367 -33.6373 10.5673 -33.3481 11.0118 -32.5488 11.5421 -31.6239 11.1543 -30.7264 10.6669 -30.2189 9.98657 -29.7357 9.15279 -29.1033 8.38725 -28.7121 7.72117 -28.0097 6.86454 -27.4493 6.31322 -26.9991 5.76595 -26.9828 5.33162 -26.5307 4.95098 -26.2086 5.19947 -25.7791 5.60628 -25.4568 6.09787 -25.4387 6.82499 -25.3458 7.54666 -25.3102 8.38349 -25.2393 9.03098 -24.8817 9.51595 -24.2058 9.77595 -23.3135 9.81943 -22.5903 9.86593 -21.923 9.90705 -21.0305 9.94285 -20.2505 9.89838 -19.6377 9.85003 -19.192 9.908 -18.4142 9.85643 -17.5764 9.83844 -17.075 9.81595 -16.6211 9.82152 -16.0157 10.2765 -15.1799 10.5993 -14.4367 10.6016 -13.8872 10.7675 -13.2852 10.9309 -12.7302 11.012 -11.6141 11.0355 -10.7226 11.136 -9.8908 11.0508 -9.16189 10.8441 -8.546 10.6847 -7.87413 10.4649 -7.2606 10.1765 -6.88074 9.77113 -6.31967 9.70218 -5.37599 9.91319 -4.87612 9.90665 -4.20608 9.92573 -3.48031 9.96736 -2.64828 9.91948 -1.81057 9.96115 -0.807282 9.9518 --0.027855 9.8843 --0.752081 9.88456 --2.03146 9.91959 --2.92476 9.94002 --4.03895 9.95328 --4.76318 9.9326 --6.04626 9.97233 --6.93586 9.86425 --7.93863 9.90267 --8.77428 9.8777 --9.77663 9.89603 --10.7798 9.94277 --11.504 9.92638 --12.674 9.91078 --13.3982 10.0215 --14.4013 9.93858 --15.4048 10.0089 --16.2957 9.88017 --17.075 9.92469 --17.6878 9.95143 --18.5792 9.94126 --19.4735 9.99813 --20.473 9.89347 --21.3647 9.96261 --22.4783 9.9315 --23.7045 9.86269 --24.9858 9.89156 --25.824 9.92438 --26.601 9.82282 --28.0498 9.77438 --29.1627 9.80298 --30.2777 9.8431 --31.4481 9.89154 --32.5623 9.92407 --33.6219 9.91263 --34.8464 9.81087 --35.7935 9.85645 --36.6291 9.83217 --37.7433 9.89153 --38.4675 9.89622 --39.1943 9.85547 --39.916 10.0103 --40.8631 9.99673 --41.5306 9.95644 --42.2001 9.99526 --42.9783 10.0222 --43.7036 10.066 --44.5399 10.1084 --45.5427 10.0927 --46.4897 10.1051 --47.2697 10.1179 --48.1033 10.1233 --48.779 10.1864 --49.9437 10.4296 --50.7794 10.4231 --52.395 10.4119 --53.5649 10.3887 --55.1809 10.3502 --56.9064 10.2634 --58.5243 10.1341 --59.9715 10.2029 --61.1414 10.2087 --62.477 10.2043 --63.2026 10.1565 --64.2052 10.172 --65.375 10.2146 --67.0466 10.1996 --68.1608 10.1552 --68.885 10.1522 --69.5549 10.1887 --70.4451 10.1088 --71.3353 10.1866 --72.4492 10.2401 --73.2861 10.2751 --74.1225 10.2678 --74.9017 10.3368 --75.6816 10.3683 --76.3494 10.3453 --77.2972 10.3623 --78.2443 10.3738 --79.247 10.3957 --80.3055 10.3897 --81.5314 10.3962 --82.59 10.3249 --83.9799 10.4463 --85.2635 10.4424 --86.2662 10.3957 --87.2688 10.4357 --88.5506 10.4145 --89.8321 10.3863 --90.7782 10.4345 diff --git a/data/nazca_heron_old.dat b/data/nazca_heron_old.dat deleted file mode 100644 index 23261b8..0000000 --- a/data/nazca_heron_old.dat +++ /dev/null @@ -1,1037 +0,0 @@ --91.726 10.4022 --92.5616 10.385 --93.0053 10.4193 --93.8429 10.4444 --94.4002 10.3881 --95.1773 10.4322 --95.731 10.328 --96.0661 10.0034 --95.7371 9.52215 --95.0108 9.51904 --93.8987 9.40352 --93.063 9.41048 --92.1174 9.36365 --91.1689 9.32841 --90.1664 9.32695 --89.2738 9.29848 --87.9935 9.21778 --87.1011 9.24003 --85.9323 9.16578 --84.818 9.2136 --83.8152 9.2263 --82.3111 9.25894 --81.2523 9.21521 --80.3055 9.26966 --79.1913 9.27179 --78.3561 9.26927 --77.4071 9.2506 --76.2938 9.15212 --75.2359 9.21265 --74.2889 9.23221 --73.2304 9.22176 --72.3344 9.24597 --71.3911 9.06377 --70.7225 9.00533 --69.8321 8.87212 --68.5508 8.90126 --67.2126 8.90584 --66.2109 8.83119 --65.1525 8.76935 --64.2054 8.77328 --62.9784 8.69629 --62.0884 8.7899 --61.1999 8.81082 --60.4738 8.81708 --59.6372 8.77889 --58.3559 8.77041 --57.8008 8.75645 --57.2974 8.71659 --56.6289 8.69558 --55.7933 8.71756 --55.1804 8.7228 --54.4562 8.71456 --53.3976 8.71721 --52.2278 8.78652 --51.4479 8.73714 --50.4451 8.74938 --49.8323 8.77075 --48.6067 8.78685 --47.7153 8.78148 --46.9345 8.79131 --45.8212 8.72036 --44.9864 8.73653 --43.76 8.7899 --43.2029 8.80459 --42.5953 8.82626 --42.0346 8.81404 --41.4759 8.75151 --40.7516 8.71843 --40.1388 8.78394 --39.5817 8.75781 --39.1361 8.75758 --38.6347 8.80655 --38.2447 8.77854 --37.8547 8.74123 --37.4091 8.7923 --35.9611 8.78602 --34.6793 8.78076 --33.8436 8.83903 --32.8966 8.83963 --32.0052 8.8087 --31.0024 8.86909 --29.9997 8.8264 --29.1083 8.82878 --27.7705 8.83849 --26.5457 8.72773 --25.4873 8.7165 --24.2616 8.6655 --23.0892 8.68424 --22.1449 8.54477 --20.8074 8.50105 --19.5257 8.45263 --17.9667 8.37676 --16.6851 8.31799 --15.5706 8.3359 --14.401 8.27044 --13.2307 8.27746 --12.5648 8.24932 --11.7826 8.30542 --11.225 8.26741 --10.6119 8.33761 --9.94418 8.2737 --9.10957 8.29055 --8.16166 8.32522 --7.15627 8.31888 --6.10021 8.19418 --5.04173 8.20764 --4.20608 8.21455 --3.25902 8.21726 --2.09019 8.14631 --1.30858 8.09495 --0.306399 8.16141 -0.528273 8.19199 -1.97994 8.12994 -2.75763 8.20323 -3.48095 8.19986 -4.54034 8.18316 -5.26597 8.14464 -5.93308 8.20355 -6.37876 8.23306 -6.93779 8.20172 -7.38503 8.28515 -7.75928 8.14925 -8.10818 7.83366 -8.55309 7.68152 -9.27282 7.59373 -10.1085 7.35329 -10.6702 7.35345 -11.5114 7.20388 -12.5089 7.36493 -13.4027 7.4728 -14.412 7.6901 -15.1803 8.05105 -15.6266 8.26723 -16.2416 8.29494 -17.0758 8.37201 -17.9672 8.45068 -18.6906 8.3527 -19.4689 8.36621 -20.0833 8.32903 -20.8076 8.36605 -21.5349 8.39958 -22.811 8.30214 -23.5936 8.32996 -24.2817 8.11023 -24.3617 7.60334 -24.4628 6.99157 -24.4059 6.20837 -24.5479 5.43455 -24.7617 4.81808 -25.0482 4.37841 -25.4039 3.83047 -25.9341 3.55091 -26.5429 3.48577 -27.1405 3.94951 -27.7711 4.42902 -28.3433 5.30396 -29.0083 5.9264 -29.3964 6.59346 -30.0334 7.39695 -30.4568 7.93096 -30.9385 8.5706 -31.4443 9.3344 -31.9062 9.83899 -32.3178 9.99556 -32.4543 9.44194 -32.3424 8.99712 -32.3298 8.3286 -32.2872 7.66008 -32.3614 7.04572 -32.2586 6.26963 -32.1964 5.65849 -32.1029 4.76416 -32.0489 3.98324 -32.0854 3.31228 -31.9712 2.75763 -32.0396 2.13545 -31.8344 1.53202 -31.8289 0.861208 -31.99 0.183618 -32.3457 -0.243851 -32.8982 -0.739612 -33.7837 -0.849395 -34.3622 -0.710696 -34.8876 -0.0191316 -35.4023 0.808785 -35.7456 1.19234 -36.2095 1.94174 -36.8011 2.75484 -37.2693 3.52304 -37.7639 4.47142 -38.2574 5.25764 -38.5964 5.86575 -39.0468 6.53111 -39.4802 7.20908 -39.8636 7.93611 -40.3677 8.68935 -40.853 9.50473 -41.3001 10.2266 -41.5896 10.8341 -41.8697 11.2788 -42.1444 11.7269 -42.4414 12.3274 -42.8817 13.0026 -43.044 13.3927 -43.2547 13.7354 -43.8157 14.4808 -44.21 14.4567 -44.2384 13.7881 -44.214 13.1202 -44.2478 12.3397 -44.2545 11.504 -44.2471 10.2762 -44.383 9.55421 -44.3819 8.8306 -44.4857 7.99434 -44.4374 7.1038 -44.4823 6.49018 -44.5055 5.54178 -44.3968 4.65176 -44.4035 3.87539 -44.3112 3.09147 -44.3678 2.31195 -44.3634 1.64156 -44.4741 1.08215 -44.7443 0.405587 -45.098 -0.0812431 -45.5916 -0.319965 -46.0404 -0.518244 -47.0404 -0.187042 -47.6198 0.241597 -48.0225 1.04872 -48.4879 1.70359 -49.0113 2.52644 -49.4565 3.30864 -49.7829 4.08959 -50.2298 4.64717 -50.7013 5.35933 -50.968 6.06294 -51.3782 6.77734 -51.8168 7.50498 -52.2817 8.27353 -52.5085 8.88449 -52.9297 9.67783 -53.2782 10.2838 -53.7366 10.9445 -54.1325 11.6654 -54.43 12.1549 -54.74 12.7268 -54.9842 13.2537 -55.3914 13.7539 -55.9159 14.019 -56.1591 13.621 -56.1814 12.7857 -56.0542 11.8895 -55.901 10.9481 -55.755 10.1629 -55.6441 9.16009 -55.4555 8.44064 -55.3158 7.48927 -55.1979 6.76738 -55.1458 6.04168 -55.0153 5.20856 -54.9225 4.47831 -54.6817 3.75997 -54.4404 2.76892 -54.3443 1.69915 -54.3354 0.809666 -54.1511 -0.0300711 -54.2166 -0.702496 -54.453 -1.31046 -54.6851 -1.85943 -55.1255 -2.25343 -55.7401 -2.43474 -56.4817 -2.28494 -57.1939 -1.76082 -57.67 -1.0781 -58.1661 -0.0158294 -58.7044 0.911084 -59.1398 1.69647 -59.5985 2.35776 -59.9523 3.04503 -60.2915 3.7707 -60.7648 4.36495 -61.1845 5.10498 -61.5282 5.65631 -61.9625 6.44572 -62.3804 6.92578 -62.7068 7.38979 -63.1888 7.02434 -63.7594 6.71273 -64.4182 5.92176 -64.9326 5.49007 -65.436 4.93653 -65.9846 4.48258 -66.3835 3.82101 -66.8552 3.23917 -67.3884 2.6537 -67.8008 2.17994 -68.2584 1.64344 -68.2649 0.417823 -68.2525 -0.137759 -68.212 -0.863123 -68.2058 -1.53202 -68.1769 -2.19838 -68.2882 -3.03763 -68.1923 -3.65085 -68.2978 -4.37321 -68.3021 -5.31814 -68.2969 -6.10242 -68.4 -6.88111 -68.3005 -7.82472 -68.273 -8.44002 -68.2464 -9.2692 -68.1829 -9.71818 -68.245 -10.5034 -68.3322 -11.2255 -68.3078 -11.8903 -68.2012 -12.5096 -68.3418 -13.1022 -68.6065 -13.3261 -69.0974 -13.3425 -69.0796 -12.6196 -69.0225 -11.5006 -69.1975 -10.0556 -69.2256 -8.9414 -69.243 -7.60627 -69.3237 -6.21134 -69.4118 -4.87177 -69.2502 -3.87182 -69.2618 -2.97959 -69.3274 -2.14482 -69.3415 -1.36489 -69.3206 -0.686317 -69.6114 -0.427229 -70.0984 -0.312499 -70.4035 -0.864603 -70.2948 -1.58221 -70.2543 -2.36766 -70.2135 -3.09189 -70.2426 -3.81611 -70.1699 -4.54469 -70.2999 -5.2107 -70.2593 -5.87737 -70.1916 -6.43108 -70.1723 -6.93454 -70.244 -7.43724 -70.2816 -8.16147 -70.289 -8.88495 -70.3531 -9.72134 -70.3477 -10.3873 -70.4535 -11.0022 -70.4808 -11.9497 -70.4864 -12.6171 -70.4493 -13.34 -70.6577 -13.7504 -71.1761 -14.0215 -71.6078 -13.6693 -71.7849 -12.7296 -71.7493 -11.1698 -71.7383 -10.222 -71.6867 -9.21995 -71.5978 -8.10296 -71.6945 -6.65731 -71.724 -5.6547 -71.6909 -4.93167 -71.7255 -4.0947 -71.6829 -3.09189 -71.6556 -2.31361 -71.5993 -1.80799 -71.7354 -1.15126 -72.1227 -0.732545 -72.5957 -0.924082 -72.7269 -1.42072 -72.798 -2.41973 -72.955 -3.03618 -72.9628 -3.64899 -72.95 -4.20608 -72.939 -4.93373 -73.1754 -5.7659 -73.2306 -6.60159 -73.258 -7.4394 -73.3313 -8.16212 -73.4053 -9.05141 -73.5125 -9.66491 -73.582 -10.2253 -73.6984 -11.0503 -73.9074 -11.6638 -74.2887 -12.1152 -74.8254 -12.0555 -75.0308 -11.4474 -74.9288 -10.3949 -74.7818 -9.44347 -74.6863 -8.04964 -74.5524 -7.05342 -74.5059 -5.76663 -74.406 -4.81738 -74.1716 -3.98324 -74.1828 -3.14729 -74.1627 -2.19507 -73.9711 -1.31592 -74.2954 -1.13944 -74.4945 -1.70344 -74.7325 -2.59075 -74.8428 -3.48254 -75.0145 -4.26162 -75.1478 -5.1454 -75.3825 -5.99195 -75.5103 -6.71359 -75.6344 -7.54683 -75.7996 -8.32736 -75.9504 -9.2252 -76.3494 -9.94925 -76.7611 -10.013 -77.0247 -9.55421 -77.0168 -8.60758 -76.7722 -7.66401 -76.5674 -6.32409 -76.3879 -5.43546 -76.1592 -4.37618 -76.079 -3.48081 -75.9239 -2.71101 -75.7774 -2.03729 -75.699 -1.59737 -75.9528 -1.05432 -76.6689 -0.939149 -77.1612 -1.32968 -77.4792 -1.61957 -77.9039 -1.91182 -78.1904 -1.77006 -78.6284 -1.71267 -79.0308 -1.85639 -79.5234 -2.19157 -79.7474 -2.14619 -80.2003 -2.47286 -80.416 -2.7096 -80.9208 -2.76515 -81.2445 -2.63541 -81.4789 -2.47298 -81.858 -2.71375 -82.3006 -3.00137 -82.6434 -3.14951 -82.8334 -3.30639 -82.9618 -3.5857 -83.0542 -4.13459 -83.3045 -4.51251 -83.4828 -4.53942 -83.6902 -5.01666 -84.1795 -5.22944 -84.433 -5.47731 -84.8724 -5.69724 -85.44 -5.65169 -85.2045 -4.93327 -84.9319 -4.59458 -84.5801 -4.0562 -85.0434 -4.41845 -85.4846 -4.5517 -85.822 -4.58297 -86.4291 -4.66072 -86.8641 -4.8989 -87.3249 -5.1661 -87.7599 -5.17183 -88.1596 -5.38038 -88.8845 -5.54301 -89.0758 -5.03874 -88.9908 -4.60685 -88.4392 -4.31739 -87.9944 -3.92687 -87.8263 -3.73325 -87.3787 -3.69144 -86.9907 -3.74579 -86.667 -3.74799 -86.307 -3.39915 -86.1521 -3.29102 -85.5422 -3.20372 -84.9936 -3.25056 -84.8131 -3.09682 -84.6518 -2.92498 -84.7139 -2.70778 -84.9344 -2.41951 -84.5395 -1.91678 -84.1568 -1.92933 -83.8164 -2.26671 -83.3204 -2.25906 -82.8592 -2.28033 -82.4168 -2.10331 -81.8816 -1.84037 -81.4293 -1.57093 -81.032 -1.35101 -80.3612 -1.25898 -79.9668 -1.28969 -79.5208 -1.24133 -79.0219 -1.15593 -78.3544 -1.03266 -77.9372 -0.724926 -77.6381 -0.532779 -78.1321 -0.412019 -79.022 -0.334834 -79.7365 -0.403715 -80.53 -0.579743 -81.084 -0.760943 -81.8071 -0.895225 -82.4782 -0.914448 -82.9781 -0.930945 -83.4276 -0.936112 -84.3706 -1.03896 -85.2088 -1.1944 -85.9289 -1.39795 -87.0464 -1.4622 -87.9377 -1.49596 -88.659 -1.51403 -90.0546 -1.58832 -90.7826 -1.72732 -91.6118 -1.8804 -92.4502 -2.01859 -93.3968 -2.0376 -94.4012 -2.15891 -95.1315 -2.09807 -95.6052 -1.6493 -95.6245 -0.920633 -95.0142 -0.412069 -94.0101 -0.144715 -93.1187 -0.189432 -92.1155 -0.184855 -90.8904 -0.243803 -89.5533 -0.237599 -88.6615 -0.236242 -87.1578 -0.303836 -85.8783 -0.270527 -84.7623 -0.250566 -83.5943 -0.129718 -82.7553 0.0179645 -81.1995 0.260974 -80.5318 0.411907 -80.9183 0.658629 -82.1999 0.635839 -84.0376 0.771737 -86.0993 0.803398 -88.1648 0.84411 -89.609 0.65952 -91.2238 0.624693 -92.3389 0.58028 -94.4558 0.66607 -95.2629 0.660988 -95.5713 1.03034 -95.7391 1.81258 -95.4034 2.13092 -94.1247 2.06277 -92.2822 1.89953 -90.2776 1.75379 -88.6628 1.83331 -87.0464 1.86452 -85.2636 1.86765 -83.8709 1.82 -82.2554 1.79107 -81.0865 1.79007 -80.1157 1.74386 -80.1334 1.93887 -81.0811 2.23192 -82.7003 2.42892 -84.5395 2.65818 -86.0436 2.63221 -87.6047 2.63459 -88.7183 2.74889 -90.334 2.88772 -91.8931 2.83109 -93.0628 2.81122 -94.1236 2.69508 -94.8341 2.93287 -95.2499 3.48754 -95.0085 4.03008 -94.3443 4.37434 -92.8445 4.17146 -91.5055 4.02086 -90.1646 3.8803 -88.9421 3.6319 -87.1005 3.49 -85.9879 3.25387 -85.0421 3.24464 -83.7595 3.20743 -82.9798 3.14365 -81.8622 3.11751 -80.976 2.96988 -80.0621 2.84425 -81.0885 3.47024 -81.9378 3.6489 -82.4922 3.83974 -83.3647 4.27166 -84.0266 4.62188 -84.5386 4.82064 -84.9745 5.02323 -85.3698 4.81152 -85.7651 4.6058 -86.4328 4.548 -86.9687 4.59919 -87.0659 4.99771 -86.8618 5.24124 -86.6658 5.44818 -86.2668 5.6535 -87.1019 5.87851 -87.7698 5.99097 -88.3791 6.22568 -89.1112 6.4213 -89.7168 6.61037 -90.3558 6.91892 -90.7855 7.21441 -90.7737 7.54215 -90.5004 7.77089 -89.9933 7.79614 -89.2749 7.60375 -88.4356 7.44428 -87.8883 7.17135 -87.6597 7.26648 -87.2029 7.22145 -87.0047 6.8102 -86.7121 6.82344 -86.3262 6.82444 -86.3146 7.16477 -86.553 7.43624 -86.6073 7.89827 -86.212 8.04484 -85.7741 7.92294 -85.3727 7.71698 -85.159 7.26678 -84.9196 6.82769 -84.8213 6.48738 -84.4684 6.12775 -83.9911 5.79129 -83.5915 5.71275 -83.1381 5.56378 -82.4792 5.26258 -81.7937 4.96558 -81.1962 4.65765 -80.7362 4.6232 -80.4787 4.909 -80.08 4.82191 -79.4998 4.23189 -78.8931 3.72655 -78.3428 3.20188 -78.3092 3.71576 -77.9599 3.9784 -77.719 4.30016 -78.0395 4.91762 -78.4051 5.49132 -78.9135 6.40463 -79.4112 7.32762 -79.9172 8.16058 -80.4247 9.10461 -80.7546 9.775 -81.0854 10.3341 -81.5764 11.0636 -81.8685 11.6162 -81.754 12.1079 -81.3082 12.1171 -81.0363 11.8892 -80.568 11.2937 -80.1876 10.7835 -79.7582 9.99418 -79.3481 9.33988 -78.8698 8.71184 -78.3571 7.77085 -78.0088 7.05571 -77.5734 6.38028 -77.1178 5.71761 -76.8005 5.15005 -76.337 4.49448 -75.9919 4.03294 -75.994 4.26179 -75.9583 4.9314 -76.3466 5.60066 -76.8133 6.4246 -77.2997 7.32439 -77.9281 8.37226 -78.6042 9.37164 -79.0863 10.2193 -79.4958 10.9289 -79.856 11.5059 -80.1477 12.0564 -80.5155 12.8522 -80.861 13.2316 -81.1485 14.0724 -80.7678 14.5459 -80.3209 14.2254 -79.9206 13.6464 -79.6606 13.0853 -79.2478 12.395 -78.8736 11.7173 -78.4521 11.0659 -78.0784 10.2776 -77.7548 9.71539 -77.29 8.8348 -76.9343 8.3413 -76.7456 7.82355 -76.4154 7.32071 -75.9858 6.4719 -75.4055 5.70854 -74.8422 4.93221 -74.6119 4.49262 -74.3462 4.09592 -74.1215 4.37322 -74.1782 5.09694 -74.8469 5.98837 -75.4801 7.25591 -76.0283 8.0968 -76.7103 9.12227 -77.398 10.5616 -77.7939 11.4511 -78.3011 12.2833 -78.8654 13.1148 -79.2539 13.7846 -79.623 14.5733 -79.9541 15.4692 -80.3716 16.2507 -80.5987 16.9298 -80.0747 17.2511 -79.5869 16.7935 -79.1336 15.9618 -78.7511 15.1781 -78.3425 14.4076 -77.8659 13.3927 -77.4296 12.4389 -76.7817 11.4001 -76.3303 10.5669 -76.0301 9.87661 -75.4467 9.22674 -74.962 8.32609 -74.622 7.71632 -74.2949 6.98872 -73.7711 5.93905 -73.5375 5.33381 -73.2448 4.64053 -72.84 4.14617 -72.2613 4.19979 -72.1516 4.60385 -72.4467 5.32227 -72.8275 6.05278 -73.3687 6.80996 -74.1322 8.26793 -74.6116 9.3374 -75.1627 10.3982 -75.6426 11.3286 -76.0586 12.2348 -76.3405 12.7905 -76.8518 13.7323 -77.198 14.5048 -77.7446 15.4027 -78.1249 16.0761 -78.3535 16.5196 -78.687 16.9633 -78.637 17.4934 -78.067 17.5349 -77.669 17.2531 -77.3505 16.6867 -77.0095 16.1879 -76.6357 15.3447 -76.179 14.4034 -75.8572 13.8396 -75.458 13.0644 -74.8572 11.9994 -74.4823 11.2672 -74.0028 10.4494 -73.6473 9.65219 -73.242 8.87957 -72.7264 7.93995 -72.3241 7.16613 -71.8701 6.28093 -71.5224 5.58931 -71.194 4.91632 -70.6833 4.02852 -70.1796 3.41292 -69.7207 2.8571 -69.2136 2.86331 -68.7805 3.32243 -68.1988 3.80251 -67.6737 4.55604 -67.0607 5.11157 -66.5602 5.61566 -66.0439 6.04454 -65.542 6.65693 -65.0516 7.28061 -64.4886 7.83231 -63.8682 8.38166 -63.4806 8.82701 -62.6509 8.98197 -61.8701 8.71545 -61.5024 8.14539 -61.1667 7.58665 -60.7729 7.03534 -60.4889 6.53788 -60.1274 5.88575 -59.7446 5.45344 -59.5827 4.81796 -59.1301 4.26463 -58.8581 3.70411 -58.481 3.13902 -58.1724 2.71238 -57.7765 2.10247 -57.4722 1.52727 -57.0016 0.817253 -56.6784 0.198728 -56.354 -0.372287 -55.7403 -0.584321 -55.6175 -0.083565 -55.6389 0.638398 -55.8152 1.58658 -55.8485 2.64634 -56.0662 3.48261 -56.2021 4.3124 -56.5438 5.76862 -56.6148 7.00231 -56.7995 7.71535 -56.9572 8.59928 -57.0697 9.66596 -57.1411 10.4998 -57.2485 11.2812 -57.2209 12.0068 -57.2864 12.8427 -57.4071 13.621 -57.4292 14.4641 -57.1339 15.0174 -56.756 15.5683 -55.8035 15.7749 -55.1888 15.45 -54.702 14.9986 -54.3267 14.5244 -53.8733 13.8576 -53.4584 13.0049 -53.0047 12.3416 -52.5121 11.5011 -52.213 10.9564 -51.9035 10.2931 -51.5297 9.9067 -51.116 9.16314 -50.8362 8.55092 -50.4922 7.83421 -50.0078 7.21066 -49.7895 6.70805 -49.5116 5.97696 -49.1128 5.5406 -48.714 4.82213 -48.2439 4.27275 -47.9923 3.53879 -47.4039 2.74948 -47.1212 1.96748 -46.7692 1.35872 -46.3782 1.30907 -45.9053 1.69915 -45.869 2.64621 -45.9339 3.87182 -45.9591 5.37443 -46.0595 6.32305 -45.9919 7.60484 -45.8376 8.88829 -45.6288 9.94298 -45.6099 11.1148 -45.5345 12.0054 -45.5154 12.8441 -45.6385 13.8427 -45.5997 14.5682 -45.5452 15.6848 -44.9829 16.225 -44.0949 16.4052 -43.265 15.9555 -42.7019 15.2921 -42.1312 14.4089 -41.6672 13.5517 -41.1422 12.6737 -40.8033 12.008 -40.2677 11.2383 -40.065 10.5723 -39.4596 9.8392 -38.9891 8.98232 -38.3485 8.16589 -37.959 7.49736 -37.5209 6.76843 -37.0109 6.16027 -36.5893 5.31344 -36.0748 4.14867 -35.5462 3.32695 -35.0692 2.31194 -34.7339 1.6445 -34.1748 1.06472 -33.7977 1.14943 -33.2575 1.81321 -33.45 3.03618 -33.4054 4.20571 -33.4258 5.32202 -33.5421 6.21163 -33.5726 7.65692 -33.5749 8.77428 -33.5748 9.55367 -33.6373 10.5673 -33.3481 11.0118 -32.5488 11.5421 -31.6239 11.1543 -30.7264 10.6669 -30.2189 9.98657 -29.7357 9.15279 -29.1033 8.38725 -28.7121 7.72117 -28.0097 6.86454 -27.4493 6.31322 -26.9991 5.76595 -26.9828 5.33162 -26.5307 4.95098 -26.2086 5.19947 -25.7791 5.60628 -25.4568 6.09787 -25.4387 6.82499 -25.3458 7.54666 -25.3102 8.38349 -25.2393 9.03098 -24.8817 9.51595 -24.2058 9.77595 -23.3135 9.81943 -22.5903 9.86593 -21.923 9.90705 -21.0305 9.94285 -20.2505 9.89838 -19.6377 9.85003 -19.192 9.908 -18.4142 9.85643 -17.5764 9.83844 -17.075 9.81595 -16.6211 9.82152 -16.0157 10.2765 -15.1799 10.5993 -14.4367 10.6016 -13.8872 10.7675 -13.2852 10.9309 -12.7302 11.012 -11.6141 11.0355 -10.7226 11.136 -9.8908 11.0508 -9.16189 10.8441 -8.546 10.6847 -7.87413 10.4649 -7.2606 10.1765 -6.88074 9.77113 -6.31967 9.70218 -5.37599 9.91319 -4.87612 9.90665 -4.20608 9.92573 -3.48031 9.96736 -2.64828 9.91948 -1.81057 9.96115 -0.807282 9.9518 --0.027855 9.8843 --0.752081 9.88456 --2.03146 9.91959 --2.92476 9.94002 --4.03895 9.95328 --4.76318 9.9326 --6.04626 9.97233 --6.93586 9.86425 --7.93863 9.90267 --8.77428 9.8777 --9.77663 9.89603 --10.7798 9.94277 --11.504 9.92638 --12.674 9.91078 --13.3982 10.0215 --14.4013 9.93858 --15.4048 10.0089 --16.2957 9.88017 --17.075 9.92469 --17.6878 9.95143 --18.5792 9.94126 --19.4735 9.99813 --20.473 9.89347 --21.3647 9.96261 --22.4783 9.9315 --23.7045 9.86269 --24.9858 9.89156 --25.824 9.92438 --26.601 9.82282 --28.0498 9.77438 --29.1627 9.80298 --30.2777 9.8431 --31.4481 9.89154 --32.5623 9.92407 --33.6219 9.91263 --34.8464 9.81087 --35.7935 9.85645 --36.6291 9.83217 --37.7433 9.89153 --38.4675 9.89622 --39.1943 9.85547 --39.916 10.0103 --40.8631 9.99673 --41.5306 9.95644 --42.2001 9.99526 --42.9783 10.0222 --43.7036 10.066 --44.5399 10.1084 --45.5427 10.0927 --46.4897 10.1051 --47.2697 10.1179 --48.1033 10.1233 --48.779 10.1864 --49.9437 10.4296 --50.7794 10.4231 --52.395 10.4119 --53.5649 10.3887 --55.1809 10.3502 --56.9064 10.2634 --58.5243 10.1341 --59.9715 10.2029 --61.1414 10.2087 --62.477 10.2043 --63.2026 10.1565 --64.2052 10.172 --65.375 10.2146 --67.0466 10.1996 --68.1608 10.1552 --68.885 10.1522 --69.5549 10.1887 --70.4451 10.1088 --71.3353 10.1866 --72.4492 10.2401 --73.2861 10.2751 --74.1225 10.2678 --74.9017 10.3368 --75.6816 10.3683 --76.3494 10.3453 --77.2972 10.3623 --78.2443 10.3738 --79.247 10.3957 --80.3055 10.3897 --81.5314 10.3962 --82.59 10.3249 --83.9799 10.4463 --85.2635 10.4424 --86.2662 10.3957 --87.2688 10.4357 --88.5506 10.4145 --89.8321 10.3863 --90.7782 10.4345 diff --git a/data/nazca_monkey.dat b/data/nazca_monkey.dat deleted file mode 100644 index 623f9b9..0000000 --- a/data/nazca_monkey.dat +++ /dev/null @@ -1,1204 +0,0 @@ --30.7428 -41.7049 --31.9015 -40.832 --32.6739 -40.444 --34.5123 -40.5501 --35.9626 -40.5436 --37.0264 -40.7339 --37.9951 -41.5062 --38.0928 -42.5706 --37.8 -43.9196 --36.3507 -44.4093 --34.8902 -44.5997 --34.5131 -45.9623 --33.1567 -46.1557 --32.081 -45.9461 --31.5143 -46.6346 --31.1211 -47.5048 --31.126 -48.8594 --30.5117 -49.5416 --30.0931 -48.512 --29.8408 -47.0594 --29.6633 -48.0291 --29.8985 -49.4199 --29.8469 -50.8722 --29.0609 -51.2922 --27.7909 -51.1142 --27.6069 -49.8435 --27.9728 -47.9686 --28.6379 -45.7908 --27.6046 -47.3017 --27.3107 -48.4528 --27.1851 -49.3605 --26.2186 -49.7207 --25.3631 -48.937 --25.1855 -47.18 --25.8537 -46.0926 --26.4529 -45.673 --26.222 -45.3106 --25.4954 -46.1571 --24.8254 -46.9365 --23.9744 -46.8823 --23.1846 -45.9709 --23.3137 -44.7669 --24.4621 -44.5277 --25.4863 -44.5161 --25.9177 -43.9741 --25.6126 -42.6428 --24.4608 -41.6775 --23.7347 -41.1323 --23.1288 -40.2858 --22.2203 -39.0157 --21.4348 -37.8046 --20.772 -36.3514 --20.4854 -34.8362 --20.1788 -33.0236 --20.1072 -29.0304 --19.9908 -26.1278 --20.4025 -24.4289 --21.0193 -23.345 --21.5604 -21.6489 --21.4991 -19.8945 --21.557 -18.0794 --21.3066 -15.7213 --20.9514 -13.6627 --20.773 -12.5735 --20.7699 -10.6377 --20.468 -9.48837 --19.7382 -8.40535 --18.9574 -7.85135 --18.0563 -7.47587 --16.8412 -6.88153 --15.5076 -6.15998 --14.1763 -5.43461 --12.9022 -5.00207 --11.9411 -5.43567 --11.5138 -6.28103 --11.4585 -7.24994 --11.2089 -8.64013 --10.9056 -10.153 --10.7902 -11.6661 --10.6087 -13.5419 --10.3656 -14.7518 --10.0651 -15.8414 --9.75352 -17.1102 --9.52007 -18.6847 --9.28164 -20.1378 --8.90539 -21.7085 --8.61497 -23.8287 --8.12303 -25.3995 --7.64123 -27.3361 --7.18957 -28.6674 --7.24708 -29.6918 --7.64695 -31.509 --8.61699 -33.685 --9.33216 -34.8417 --10.1165 -35.992 --10.9696 -37.4406 --12.1731 -39.2597 --13.2668 -41.0721 --14.1145 -42.4636 --15.5088 -44.0951 --16.4717 -45.4293 --17.0771 -46.46 --17.8067 -47.0608 --19.0161 -46.9341 --20.4686 -46.7507 --22.0444 -46.6937 --22.5213 -47.0025 --22.8815 -47.7262 --22.8927 -48.5094 --23.372 -49.0596 --24.1027 -49.4233 --23.2539 -50.4537 --21.9225 -50.9373 --20.7099 -51.3541 --19.4427 -51.906 --18.4113 -52.384 --17.6251 -52.8084 --16.776 -53.4695 --15.9321 -53.8998 --14.9051 -54.3849 --14.2952 -54.863 --13.753 -55.3509 --13.2689 -55.3497 --12.9663 -54.5027 --12.6041 -54.0115 --11.3927 -53.8995 --10.1243 -53.4735 --9.76015 -52.3247 --10.0637 -51.543 --11.2758 -51.1809 --11.9967 -50.7496 --12.7219 -50.0849 --13.0258 -49.239 --12.9044 -48.514 --12.1212 -47.603 --11.1534 -46.817 --10.4291 -45.8471 --9.75574 -45.1273 --9.1506 -44.282 --8.5458 -43.7349 --8.06811 -42.8234 --7.22182 -41.734 --6.49384 -40.7067 --5.70662 -39.6787 --5.10459 -38.8903 --4.50083 -37.9221 --3.77308 -36.4706 --3.35045 -35.7445 --2.80372 -34.5353 --2.38739 -33.6864 --1.83611 -31.995 --1.71118 -30.1802 --1.65053 -28.4256 --1.52958 -27.0339 --1.5293 -25.4606 --1.70693 -23.7646 --2.18951 -22.4325 --3.1009 -20.3168 --3.71033 -18.4425 --3.95051 -17.2926 --4.43971 -15.4788 --4.85498 -13.9033 --5.52524 -11.7266 --5.96218 -10.0364 --6.37058 -8.57986 --6.91724 -7.12857 --7.34478 -5.98087 --7.82366 -4.88951 --8.25198 -3.91841 --7.46002 -2.6517 --6.18748 -1.86782 --4.73837 -0.834822 --3.04648 0.0767719 --1.70745 0.788371 -0.0431392 1.76356 -1.80011 2.66568 -3.24563 3.34625 -5.00218 4.06908 -6.39434 4.43025 -8.02861 4.791 -10.3275 4.66822 -11.6586 4.60952 -12.8681 4.42731 -14.3155 3.39263 -15.5896 2.42917 -16.8675 1.46808 -17.8306 0.314723 -19.0406 -0.53289 -19.8278 -1.92397 -20.4824 -2.84096 -21.399 -3.86138 -22.1875 -5.13064 -23.1443 -6.472 -23.9408 -7.3097 -24.6047 -8.15785 -25.2695 -9.18616 -25.6921 -10.3325 -25.212 -11.0621 -23.5782 -11.7901 -22.9752 -11.8532 -22.3689 -12.0918 -20.8613 -12.8278 -20.0075 -13.2369 -19.2237 -13.4852 -18.0152 -14.0951 -16.3767 -14.7494 -15.2282 -15.3562 -14.2026 -15.7854 -12.8666 -16.5033 -11.7182 -17.3527 -10.8141 -18.5655 -9.53574 -20.0118 -8.39731 -21.7128 -7.48394 -23.3431 -7.06224 -24.3724 -6.57641 -25.6423 -6.26354 -27.2762 -6.32905 -29.4555 -6.75744 -30.9667 -7.12281 -32.1759 -7.71138 -33.576 -8.26694 -34.5989 -8.93741 -35.7461 -9.18345 -36.8342 -9.53469 -38.3168 -10.1418 -39.6813 -10.757 -40.8869 -11.2907 -42.2826 -11.8365 -43.7343 -12.3871 -45.1229 -13.47 -46.7602 -14.1404 -47.9676 -14.7486 -49.175 -15.354 -49.9636 -15.5319 -50.6912 -15.2944 -51.422 -14.5593 -52.2024 -14.3872 -52.8082 -14.4349 -54.0826 -15.1103 -55.4068 -16.3106 -56.445 -17.6473 -57.8926 -19.1607 -58.8599 -20.6114 -59.4008 -21.5216 -58.7983 -21.3393 -57.2858 -20.1289 -56.6812 -19.2242 -56.1949 -18.5549 -55.2203 -18.981 -55.1654 -20.0706 -55.7083 -21.0367 -56.1364 -22.2478 -56.4339 -23.7593 -56.737 -25.5142 -56.6832 -28.0551 -56.4987 -29.3844 -56.3169 -29.8045 -55.3522 -29.2041 -54.0813 -27.5106 -53.533 -25.2108 -53.4646 -22.8525 -53.6506 -21.2177 -53.4764 -20.0046 -53.2338 -19.8267 -52.8757 -21.0367 -52.878 -22.5493 -52.8726 -24.3041 -52.8636 -25.9989 -52.9346 -27.6314 -52.6259 -29.203 -52.1412 -30.4174 -50.9331 -30.5433 -49.2327 -29.9903 -48.5758 -29.2023 -48.2613 -27.815 -48.6364 -26.4842 -49.5436 -25.3913 -50.5657 -24.3644 -50.9891 -22.7312 -50.9891 -20.854 -50.8134 -20.3113 -50.3906 -21.4603 -50.0877 -22.8517 -50.0837 -24.366 -49.9678 -25.6343 -49.2986 -26.533 -48.4534 -26.3655 -46.9966 -25.877 -46.3945 -24.2416 -46.391 -22.6083 -47.1188 -20.7947 -48.2707 -19.7056 -48.8164 -18.4934 -48.7579 -17.5893 -48.1488 -16.7442 -46.9383 -16.1969 -45.6083 -15.773 -44.1565 -15.4101 -42.5833 -15.1028 -41.9802 -14.6198 -40.83 -14.1379 -39.5586 -13.5343 -37.501 -12.9928 -36.1687 -12.6267 -35.2624 -12.3826 -34.3555 -12.0254 -33.3255 -11.7725 -32.1803 -11.2934 -31.2096 -10.6292 -29.696 -10.5609 -28.0621 -10.6287 -26.3071 -11.1064 -25.2745 -11.8375 -24.1265 -13.5386 -22.6826 -14.8678 -21.5306 -16.0731 -20.3739 -17.4085 -19.7163 -18.9193 -18.8058 -19.9443 -18.1952 -20.8539 -17.5933 -22.1837 -16.7435 -23.2749 -16.1424 -24.4268 -15.4203 -25.5762 -14.7543 -26.6049 -14.0899 -27.6317 -13.6011 -28.7782 -13.6077 -29.8105 -14.146 -30.4746 -14.9945 -31.6229 -15.9032 -32.3546 -16.62 -33.863 -17.4194 -35.9204 -17.5919 -37.5539 -17.4732 -39.3063 -16.8658 -40.5808 -15.903 -41.6708 -15.1221 -42.6364 -14.8171 -43.9099 -14.8699 -44.8106 -15.784 -45.4759 -16.5088 -45.9072 -17.2298 -46.7569 -18.3779 -47.2999 -19.2262 -47.8995 -20.258 -48.441 -21.1066 -49.1718 -22.4957 -49.8411 -23.7649 -50.261 -24.8554 -50.6844 -26.1258 -51.3432 -27.2184 -52.0128 -28.5471 -52.4356 -29.8788 -52.9812 -31.0879 -53.2264 -32.4788 -52.9292 -34.5991 -52.6208 -35.5651 -52.3702 -36.9537 -51.8344 -38.4092 -51.2848 -39.4961 -50.8656 -40.5265 -50.1384 -41.4935 -49.4745 -42.04 -48.6896 -42.6465 -47.9002 -43.4299 -46.9315 -43.8524 -45.843 -44.5189 -44.1492 -45.3683 -42.9996 -45.3687 -42.213 -45.3665 -42.0876 -44.0362 -41.8475 -42.645 -41.1836 -41.1923 -40.5177 -39.9227 -39.6116 -39.1343 -38.7646 -38.5893 -37.3727 -38.2262 -35.3148 -38.4068 -34.0449 -38.9526 -32.4121 -39.6194 -31.3287 -40.5244 -31.5633 -41.3744 -32.2307 -42.0364 -33.6215 -42.5244 -34.9542 -42.5289 -35.8608 -42.2824 -37.0702 -41.8572 -38.4589 -41.9818 -39.1861 -42.5845 -39.7401 -43.4291 -39.9053 -44.5195 -39.9179 -45.4878 -39.8518 -46.2131 -39.7323 -46.6372 -38.8849 -45.6699 -37.9769 -45.1254 -37.1902 -44.3395 -36.2245 -43.606 -35.3764 -43.4256 -34.4083 -43.3728 -32.7738 -43.4885 -31.5032 -43.853 -30.8412 -44.3985 -30.8363 -45.2489 -31.7463 -45.7881 -32.8948 -46.0252 -34.6502 -45.8527 -35.6782 -45.7909 -36.4077 -46.2121 -36.8297 -47.0625 -36.5262 -47.3 -35.5575 -47.1225 -34.0451 -46.8797 -32.4707 -46.8769 -31.45 -47.4822 -31.62 -48.0915 -32.0499 -48.9918 -33.9238 -49.537 -35.6187 -49.4852 -37.6156 -49.2303 -38.2787 -49.3022 -38.6923 -49.5404 -38.6433 -50.3241 -37.6149 -50.3287 -36.4058 -50.4527 -34.7122 -50.9357 -33.6226 -51.5381 -33.4446 -52.6205 -34.4673 -53.3562 -35.3761 -53.7163 -36.7075 -53.7201 -38.8252 -53.5349 -40.0344 -52.8079 -40.877 -52.1355 -41.6176 -51.6582 -41.6639 -52.5038 -41.1828 -53.5346 -41.2448 -54.4422 -41.7897 -55.3445 -43.1822 -55.4112 -43.9703 -54.5644 -44.3942 -53.7176 -44.9969 -52.5063 -45.7233 -50.873 -46.6295 -49.4199 -47.8306 -48.1356 -49.9597 -46.7612 -51.6502 -45.6066 -52.7398 -44.7608 -53.3463 -43.9755 -54.1328 -43.3098 -54.7386 -42.4631 -55.5839 -41.252 -56.1859 -39.9801 -56.9151 -38.348 -57.3414 -36.7753 -57.5762 -35.1417 -57.46 -33.3263 -57.577 -31.5113 -57.5276 -29.5742 -57.2169 -26.9131 -56.8517 -25.0383 -56.2514 -23.2212 -55.345 -21.8282 -54.6139 -20.9858 -53.8882 -20.1983 -53.2313 -19.1637 -52.3181 -17.897 -51.3469 -16.8109 -50.3185 -15.782 -49.6497 -14.9994 -48.8046 -14.2124 -47.9622 -13.6611 -47.053 -12.8161 -46.2088 -12.269 -45.5436 -11.422 -45.1744 -10.875 -45.7224 -10.4551 -46.4495 -10.5712 -47.5376 -10.8192 -48.3231 -10.2738 -48.6855 -9.6084 -48.9217 -8.64071 -48.9322 -7.18776 -48.687 -6.28112 -47.719 -5.91752 -46.8114 -5.73793 -46.2678 -5.73548 -45.8408 -5.31462 -45.4204 -4.64729 -45.1139 -3.6198 -44.8136 -2.46972 -44.4593 -1.43788 -43.9651 -0.170934 -43.6077 1.10209 -43.0626 2.06995 -42.5227 2.98254 -41.8518 3.70412 -40.9408 4.48593 -39.972 5.08823 -38.7622 5.6293 -37.5531 5.93722 -36.6466 6.2463 -35.0719 6.1906 -33.6843 5.87382 -32.3517 5.39473 -31.1986 4.73315 -30.5941 4.0675 -29.6825 3.22382 -29.0291 2.48877 -28.6565 1.82921 -28.2972 1.34793 -27.7532 1.34296 -27.2646 1.82245 -26.6637 2.43065 -25.6789 2.37865 -25.3234 1.58272 -25.5161 0.617623 -26.3563 -0.839496 -27.0243 -1.68382 -27.5752 -2.89216 -27.7543 -3.98076 -28.417 -4.89004 -28.7906 -5.67509 -28.9059 -6.88831 -28.5392 -7.49887 -27.7469 -7.49471 -27.2708 -6.70333 -26.7229 -5.73725 -25.9375 -4.46598 -25.3954 -3.49674 -24.8465 -2.34929 -24.2963 -1.2046 -23.7131 -0.402416 -23.0353 0.556745 -22.6693 1.34181 -22.0655 2.37112 -21.4656 3.10153 -20.794 3.88301 -20.0084 4.85178 -19.5235 5.69822 -18.9773 6.36267 -18.4349 7.15059 -17.3431 8.17513 -15.7745 9.27139 -14.8659 9.75335 -14.0228 10.3635 -13.0483 11.0803 -12.3254 11.5114 -11.6584 11.6933 -10.4477 11.6305 -9.482 11.2607 -8.26731 10.8529 -6.94585 10.4606 -5.61033 9.98824 -4.15505 9.514 -2.22019 8.90516 -1.1919 8.29614 --0.0199303 8.18336 --1.28849 7.75436 --2.19871 7.33577 --3.04031 6.84052 --4.25046 6.295 --5.34561 5.88582 --6.61384 5.27591 --7.58102 4.85026 --9.09478 4.24827 --10.9085 3.57986 --12.0619 2.85838 --13.3709 1.68589 --14.424 1.05319 --15.8701 0.433674 --17.4418 -0.236547 --19.135 -0.779826 --20.5311 -1.61977 --21.495 -2.29062 --22.5811 -3.2604 --23.4986 -4.34041 --24.2198 -5.07161 --25.3697 -5.68338 --26.2772 -5.67587 --27.2428 -5.06958 --27.7305 -4.22403 --27.8514 -2.71191 --28.3956 -1.74382 --29.0602 -0.896092 --29.9687 0.252322 --31.1132 1.04483 --32.1456 1.94842 --33.1665 2.50922 --34.4462 3.09519 --35.5969 3.63654 --37.1674 4.30817 --38.6206 4.97145 --40.1886 5.82808 --41.7665 6.66609 --43.3358 7.46006 --44.7305 8.17994 --45.8841 8.89912 --47.0233 9.58266 --48.1752 10.242 --49.3277 11.1459 --50.1754 11.8105 --51.3832 13.0839 --53.0191 14.4726 --53.9288 15.3176 --55.0799 16.6469 --56.2296 17.7368 --57.251 19.1335 --58.3434 20.6437 --59.3117 22.0955 --59.7364 23.0025 --60.5241 24.3332 --61.0134 25.4822 --61.2492 26.9354 --61.4966 28.5086 --61.5001 29.8999 --61.5527 31.897 --61.373 33.2889 --61.1895 34.4987 --61.0739 35.5897 --60.8013 36.4332 --60.3453 38.2508 --60.0302 39.5189 --59.802 40.974 --59.3718 42.4243 --59.0696 43.7554 --58.6505 45.1484 --58.0427 46.9627 --57.4967 48.1722 --56.7729 49.8071 --56.1624 50.7706 --54.9601 52.1099 --53.871 53.0179 --53.0793 53.6162 --52.1132 54.3449 --51.0835 55.0694 --50.1177 55.6784 --48.9671 56.2818 --47.6368 56.8886 --46.5455 57.3672 --44.9133 57.7944 --43.2201 58.646 --41.6455 59.0666 --40.2527 59.1797 --39.4067 59.3662 --37.9538 59.7225 --36.3207 59.9136 --33.9616 59.7806 --31.2976 59.6763 --29.3637 59.301 --26.8242 58.8156 --25.7314 58.3412 --24.9499 58.0887 --23.916 57.4928 --22.8936 56.8787 --21.9187 56.1612 --21.0804 55.3049 --19.9861 54.2822 --19.1371 53.3159 --17.8016 51.9866 --17.2631 50.8942 --16.4084 49.9914 --15.7495 48.838 --14.9606 47.5082 --13.9909 45.8135 --13.6308 44.0582 --13.5106 41.88 --13.6389 39.4009 --13.9966 37.8268 --14.5401 36.2534 --14.9668 35.4087 --15.6969 34.3211 --16.2975 33.1691 --16.8985 31.9569 --17.5632 30.9276 --18.4109 29.8393 --18.8967 28.7513 --19.7444 27.6627 --20.5261 26.5108 --21.0079 25.177 --21.9253 23.9139 --22.828 22.821 --23.1992 22.1008 --24.0365 20.9427 --25.369 20.0365 --26.4588 19.554 --28.0325 19.0722 --29.3022 18.7057 --30.3902 18.5203 --31.7832 18.1658 --33.8402 18.1024 --36.6239 18.0346 --38.194 18.168 --39.4066 18.7066 --40.9821 18.8861 --41.8828 19.8016 --42.7958 20.5213 --43.638 21.677 --44.9124 22.5793 --46.0601 23.4883 --47.0895 24.7583 --48.4158 26.2728 --49.0205 27.5445 --49.9332 28.9932 --50.6053 30.1997 --51.3294 31.5324 --52.0559 33.3476 --52.6599 35.2244 --52.832 37.524 --52.9632 40.3071 --52.8963 41.6371 --52.2953 43.3327 --51.4457 45.2071 --50.5427 46.9044 --49.6342 48.054 --48.6021 49.0178 --46.6024 50.4055 --45.6969 51.0725 --44.6091 51.6192 --43.4626 52.1116 --42.2511 52.5329 --40.6794 52.8364 --39.4073 53.3791 --38.2573 53.6273 --36.2602 53.6861 --34.1431 53.6154 --32.5699 53.3747 --31.2987 52.954 --29.9644 52.6575 --29.057 52.2321 --27.3612 51.262 --26.945 50.7107 --26.152 50.1131 --25.4303 49.4429 --24.4624 48.2931 --23.8513 47.6927 --23.0672 46.6625 --22.3478 45.7507 --21.3816 43.5738 --21.2542 41.759 --21.3195 39.5823 --21.8588 38.2494 --22.1056 36.7382 --22.7075 34.8615 --23.1298 33.7113 --24.0362 32.0162 --24.9486 30.7492 --25.8552 29.5991 --26.7565 28.6256 --27.3631 27.8976 --28.3979 27.3643 --29.9682 26.4519 --31.1229 25.7988 --32.1465 25.3635 --33.5363 24.8757 --34.4452 24.3966 --36.441 24.518 --37.1709 24.7485 --38.2592 25.1163 --39.1628 25.6073 --40.0135 26.1461 --41.4581 27.122 --42.3713 28.1456 --43.0962 29.1148 --43.8784 29.904 --44.5442 30.8725 --45.2831 31.7732 --45.7551 33.1688 --46.1888 34.4966 --46.6083 35.8291 --46.9069 37.0402 --47.1475 38.0682 --47.1492 38.9754 --46.8545 40.43 --46.2991 41.9972 --45.6932 42.7837 --45.1551 43.6355 --44.1848 44.359 --43.2796 45.2698 --41.464 46.2369 --40.1921 46.8347 --38.257 47.163 --36.26 47.1469 --33.9001 46.8433 --31.8414 46.1781 --29.9634 44.4849 --29.0066 43.1475 --28.0868 41.215 --27.9107 39.6413 --27.9061 37.8249 --28.397 36.0121 --29.1777 34.3144 --29.7883 33.4717 --30.5184 32.749 --31.2997 31.8368 --32.0245 30.9875 --33.6592 30.4384 --35.1738 30.5576 --36.7427 31.0522 --37.957 31.8935 --39.1621 32.8065 --40.1912 34.0156 --40.9207 35.2241 --41.2192 36.072 --41.4701 37.524 --41.4003 38.9729 --40.6814 39.7076 --39.7649 40.3627 --39.1049 41.0342 --38.3799 41.4658 --36.8688 41.7504 --35.4709 41.218 --34.6251 40.551 --33.6002 39.7018 --33.5932 38.3712 --33.5286 37.5195 --33.9003 36.7325 --34.6258 36.6815 --35.4775 36.8556 --36.0816 37.7042 --36.566 38.9716 --37.0469 39.3366 --38.2579 39.3398 --39.0989 38.6115 --39.4593 37.1642 --38.7312 35.5404 --37.3482 34.5009 --35.9581 33.8375 --34.4416 33.8857 --33.2942 34.4366 --32.325 35.5254 --31.5431 36.7376 --31.1787 38.6129 --30.9989 40.4876 --31.4768 41.8841 --32.4452 42.7909 --33.2942 43.6376 --34.1431 44.0562 --34.99 44.2371 --36.2615 44.3447 --37.1073 44.4205 --38.1362 44.3005 --39.346 43.7554 --40.5034 43.2234 --41.1665 42.7922 --41.5827 42.3019 --42.3112 41.3961 --43.0321 40.1236 --43.5829 38.6736 --43.8213 37.4632 --43.8216 36.0719 --43.5748 34.8022 --43.3994 33.8332 --42.8629 32.7981 --42.2488 32.0799 --41.4058 31.2287 --40.5573 30.383 --39.768 29.7219 --38.8039 29.229 --37.3487 28.6323 --35.5948 28.1452 --34.0216 28.1429 --31.6015 28.2664 --30.4013 29.0031 --29.2452 30.084 --27.9715 31.8968 --27.128 33.1694 --26.0975 35.044 --25.3043 36.4342 --25.1326 38.9761 --25.0111 40.7297 --25.2416 42.1865 --25.8542 43.2711 --26.754 44.3055 --27.9737 45.931 --29.0659 46.8355 --30.2076 47.9336 --31.4242 48.8215 --33.1146 49.2578 --35.5345 49.5011 --37.5918 49.6921 --40.1321 49.5581 --42.4918 49.3812 --44.4291 48.6577 --45.9436 47.8118 --46.7291 46.9636 --47.3306 46.2349 --48.1181 45.1466 --48.9089 43.878 --49.3322 42.9098 --49.8164 41.8209 --50.181 40.9729 --50.3659 39.1555 --50.0582 37.8255 --49.699 36.3711 --49.2196 35.278 --48.9029 34.8016 --48.609 33.4086 --48.4211 32.0788 --47.8754 31.2319 --47.4493 30.0238 --46.6062 28.6298 --45.6973 27.2408 --44.4897 26.4506 --43.095 25.3054 --41.1545 24.042 --40.0092 23.3096 --38.5014 22.4527 --36.8047 21.7331 --34.6278 21.1918 --32.5695 21.6711 --30.4434 21.9618 --28.8776 23.0603 --27.485 23.6641 --26.1587 24.3977 --25.371 25.0008 --24.4095 25.9118 --23.4891 27.4132 --22.411 28.2697 --21.7333 29.5336 --21.1339 30.5654 --20.4702 31.5346 --19.8096 32.6257 --19.3826 33.5921 --18.6606 35.3473 --18.1737 37.2217 --17.9887 38.7339 --17.7493 40.6094 --17.7486 42.6662 --18.0415 44.7866 --18.6544 46.599 --19.6201 48.2947 --20.406 49.324 --21.4951 50.536 --22.7053 51.2609 --24.0393 52.2857 --25.5549 53.4316 --26.4563 54.167 --27.853 54.8844 --28.7566 55.4969 --29.7855 55.8596 --31.1175 56.2804 --32.5694 56.6505 --34.99 56.7094 --36.5625 56.6397 --37.5916 56.5228 --38.8015 56.4015 --39.7102 56.4041 --40.5563 56.0997 --41.6459 56.0422 --43.0397 55.8022 --44.0647 55.309 --45.3377 55.0141 --46.6648 54.5217 --48.1815 53.6211 --49.142 53.0657 --50.1875 52.2988 --50.9639 51.5613 --51.5045 50.65 --52.2368 49.9898 --52.9014 49.0211 --53.5683 48.0527 --53.7482 47.5079 --54.2966 46.4202 --54.6512 45.5094 --55.074 44.2993 --55.2525 43.6336 --55.4425 42.486 --55.8588 41.4565 --55.8658 40.852 --56.1035 39.9431 --56.5227 38.794 --56.5962 37.5853 --56.7705 36.5557 --56.6505 35.5271 --56.4755 34.4346 --56.1646 33.8334 --55.9183 32.8658 --55.7424 31.7154 --55.4415 31.1094 --54.8927 30.2039 --54.5315 29.2956 --54.108 28.207 --53.3248 27.3578 --52.6554 26.2106 --52.1134 25.4829 --51.5707 24.3312 --50.7863 23.4829 --50.1165 22.6393 --49.4568 21.7283 --48.8518 20.6982 --48.0615 19.734 --47.447 18.6513 --46.7768 17.7536 --46.0021 17.1333 --45.034 16.1042 --43.6419 15.2582 --42.5546 14.7656 --41.1007 14.4703 --39.7695 14.4733 --38.3774 14.3582 --36.2604 14.1698 --34.4453 14.2351 --32.3863 14.2147 --30.3308 14.4639 --28.3327 14.5277 --26.2799 15.3265 --24.7103 15.8756 --22.5273 16.9542 --21.8577 17.4345 --21.193 18.402 --20.4708 18.9505 --19.8028 19.7956 --19.0759 20.4608 --18.4072 21.7294 --17.8693 22.6408 --17.3896 23.6121 --16.5354 24.8781 --15.9304 26.2696 --15.3892 27.2999 --14.8984 28.2642 --14.2938 29.2935 --13.7572 30.5072 --13.3296 31.4734 --12.903 32.44 --12.3583 33.5899 --11.8816 34.9237 --11.2159 36.6178 --10.7238 37.7645 --10.3051 39.2178 --10.2431 40.7301 --9.70324 41.8805 --9.51718 43.3322 --9.81727 44.543 --10.3073 46.114 --10.8437 47.5095 --11.6893 49.0823 --12.303 50.7118 --13.2138 51.7975 --14.1748 52.8328 --15.0818 53.8012 --15.937 54.702 --16.7208 55.6716 --17.5007 56.4657 --18.474 57.246 --19.1371 57.8541 --19.9266 58.332 --21.1281 58.8874 --21.9811 59.79 --23.3729 60.455 --24.401 61.182 --25.3064 61.6102 --26.2157 62.0304 --27.367 62.448 --28.5165 62.6908 --29.7262 62.9936 --30.8752 63.1205 --32.3276 63.2432 --33.5982 63.2375 --35.2318 63.2364 --36.1998 63.2364 --37.4101 63.1172 --38.9226 62.8153 --40.1331 62.8163 --41.3417 62.5081 --42.4313 62.2073 --44.0055 61.848 --44.9719 61.5401 --46.0023 61.2438 --47.3328 60.8182 --48.2424 60.3981 --48.9667 59.9716 --50.1782 59.4301 --51.2046 58.9417 --52.0531 58.3994 --53.0224 57.7964 --53.5086 57.4966 --54.2878 56.9412 --54.9559 56.5217 --55.5601 55.976 --56.4747 55.3178 --56.9505 54.825 --57.4913 54.4005 --57.916 53.734 --58.3491 53.3176 --58.5851 52.8304 --59.1298 51.9828 --59.6144 51.6208 --59.9141 51.1348 --60.3397 50.5312 --60.7664 49.9277 --60.9439 49.3808 --61.5548 48.5984 --62.0352 47.87 --62.2144 47.3238 --62.7008 46.6599 --63.0658 46.056 --63.5524 45.2099 --63.9092 44.4204 --64.273 43.6948 --64.5709 42.9668 --64.8841 42.2457 --65.1832 41.6387 --65.4683 40.7245 --65.7827 39.9427 --66.0874 39.0965 --66.3992 37.7665 --66.4534 37.1609 --66.6288 35.8889 --66.8712 34.9811 --67.0559 34.438 --67.0557 33.5304 --67.0602 32.6227 --66.9928 31.7156 --66.9533 30.8683 --66.9383 29.8397 --66.9263 29.0539 --66.8729 28.2668 --66.8236 27.3578 --66.6969 26.5109 --66.3943 25.6642 --66.0922 24.5746 --65.6619 23.4878 --65.37 22.4538 --64.8782 21.6719 --64.4534 20.7046 --64.0386 19.9738 --63.3093 18.6442 --62.8256 17.8577 --62.1598 16.7081 --61.4843 15.6252 --61.0649 14.9572 --60.6401 14.3522 --60.2194 13.4436 --59.7328 12.78 --59.1336 11.9895 --58.5793 11.0268 --58.2201 10.3614 --57.5542 9.81519 --57.1374 9.14484 --56.6504 8.54221 --55.9257 7.8149 --55.3159 7.15355 --54.5954 6.30196 --53.922 5.40095 --53.1381 4.49142 --52.419 3.75688 --51.7501 3.27756 --50.8383 2.61624 --49.9314 1.64865 --48.9657 0.919663 --48.2405 0.494643 --47.2714 0.0127581 --46.5421 -0.344675 --45.4614 -0.963183 --44.4973 -1.63675 --43.3404 -2.29018 --42.3102 -2.77096 --41.4643 -3.37826 --40.1971 -3.92937 --39.2261 -4.40723 --38.3775 -4.88676 --37.2897 -5.07389 --35.8364 -5.49333 --34.8671 -5.91258 --33.297 -6.4053 --31.8465 -7.01358 --30.6357 -7.55535 --29.3056 -8.34424 --28.2725 -8.88058 --27.245 -9.54744 --26.2147 -9.90444 --25.186 -10.213 --24.7734 -11.3646 --24.6349 -12.2108 --24.7152 -13.5991 --25.0115 -14.7491 --25.5963 -15.908 --26.0307 -16.8694 --26.0797 -18.0811 --26.2151 -19.1685 --26.2802 -20.3782 --26.4075 -21.4695 --26.2138 -22.3134 --25.7295 -23.4624 --25.3056 -24.2502 --25.131 -25.4615 --24.8259 -26.8526 --24.5853 -27.881 --24.5183 -28.7883 --24.455 -29.9378 --24.3993 -31.4508 --24.4606 -33.0846 --24.703 -34.1741 --25.8635 -35.8598 --26.462 -36.652 --26.9976 -37.5042 --27.5463 -38.4706 --28.1566 -39.071 --28.824 -39.857 --29.3058 -40.5843 --29.8478 -41.3712 diff --git a/data/star.dat b/data/star.dat deleted file mode 100644 index f74f958..0000000 --- a/data/star.dat +++ /dev/null @@ -1,10 +0,0 @@ -350 75 -379 161 -469 161 -397 215 -423 301 -350 250 -277 301 -303 215 -231 161 -321 161 diff --git a/data/strange.dat b/data/strange.dat deleted file mode 100644 index 9966eb1..0000000 --- a/data/strange.dat +++ /dev/null @@ -1,16 +0,0 @@ -400 472 -500 392 -520 272 -460 232 -580 212 -480 152 -360 172 -360 52 -300 112 -200 32 -120 92 -200 72 -340 272 -208 212 -180 352 -300 312 diff --git a/data/tank.dat b/data/tank.dat deleted file mode 100644 index 4337c6d..0000000 --- a/data/tank.dat +++ /dev/null @@ -1,55 +0,0 @@ --37.317758 260.65677 --37.317758 317.44301 --34.741139 339.73612 --27.330761 354.21222 -59.525828 406.25724 -444.17643 404.87856 -538.9604 368.68832 -555.15984 355.59089 -558.95121 344.90615 -559.64054 325.94936 -568.19908 315.85885 -572.586 322.56108 -584.65003 322.31737 -568.80837 296.11771 -557.59736 289.78104 -539.56224 286.49085 -443.31476 286.82943 -389.89106 280.79772 -405.74583 272.00866 -412.98388 262.01326 -475.5413 262.1856 -480.71134 267.01096 -514.66123 266.66629 -520.34827 262.01326 -669.93463 262.01326 -670.45162 264.08127 -676.91417 263.82277 -678.03434 262.09943 -680.61936 261.66859 -683.03204 255.46455 -682.51504 249.94985 -677.862 243.91814 -668.81445 243.4873 -665.28159 247.02016 -520.86527 246.33082 -514.66123 240.12678 -479.67733 239.95444 -475.5413 243.57347 -412.98388 243.05647 -397.64611 227.54636 -324.74862 221.16998 -323.88695 214.79361 -328.36764 211.86392 -326.6443 207.03856 -300.79412 207.03856 -295.62409 211.69159 -285.28402 208.2449 -272.01426 211.17458 -96.577738 209.62357 -80.205961 211.86392 -58.491817 232.7164 -74.863594 254.94755 -168.61356 269.25131 -175.16228 276.83403 -87.271676 260.11758 diff --git a/python/bc.sh b/python/bc.sh deleted file mode 100644 index 9c1bbd2..0000000 --- a/python/bc.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -touch framework/framework.pyx -rm -rf build -python setup.py build_ext -i \ No newline at end of file diff --git a/python/framework/framework.pyx b/python/framework/framework.pyx deleted file mode 100644 index 96736ba..0000000 --- a/python/framework/framework.pyx +++ /dev/null @@ -1,136 +0,0 @@ -## -## GL convenience layer -## -from math import pi as PI - -from gl cimport * -include "polydecomp.pxi" -include "seidel.pxi" - -cdef extern from 'math.h': - double cos(double) - double sin(double) - double sqrt(double) - -SEGMENTS = 25 -INCREMENT = 2.0 * PI / SEGMENTS - -def init_gl(width, height): - glEnable(GL_LINE_SMOOTH) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glClearColor(0.0, 0.0, 0.0, 0.0) - glHint (GL_LINE_SMOOTH_HINT, GL_NICEST) - -def reset_zoom(float zoom, center, size): - - zinv = 1.0 / zoom - left = -size[0] * zinv - right = size[0] * zinv - bottom = -size[1] * zinv - top = size[1] * zinv - - # Reset viewport - glLoadIdentity() - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - - # Reset ortho view - glOrtho(left, right, bottom, top, 1, -1) - glTranslatef(-center[0], -center[1], 0) - glMatrixMode(GL_MODELVIEW) - glDisable(GL_DEPTH_TEST) - glLoadIdentity() - - # Clear the screen - glClear(GL_COLOR_BUFFER_BIT) - -def draw_polygon(verts, color): - r, g, b = color - glColor3f(r, g, b) - glBegin(GL_LINE_LOOP) - for v in verts: - glVertex2f(v[0], v[1]) - glEnd() - -def draw_line(p1, p2, color): - r, g, b = color - glColor3f(r, g, b) - glBegin(GL_LINES) - glVertex2f(p1[0], p1[1]) - glVertex2f(p2[0], p2[1]) - glEnd() - -## -## Game engine / main loop / UI -## -from glfw cimport * - -import sys - -# Keyboard callback wrapper -kbd_callback_method = None - -cdef extern void __stdcall kbd_callback(int id, int state): - kbd_callback_method(id, state) - - -cdef class Game: - - title = "Poly2Tri" - - def __init__(self, window_width, window_height): - - glfwInit() - - # 16 bit color, no depth, alpha or stencil buffers, windowed - if not glfwOpenWindow(window_width, window_height, 8, 8, 8, 8, 24, 0, GLFW_WINDOW): - glfwTerminate() - raise SystemError('Unable to create GLFW window') - - glfwEnable(GLFW_STICKY_KEYS) - glfwSwapInterval(1) #VSync on - - def register_kbd_callback(self, f): - global kbd_callback_method - glfwSetKeyCallback(kbd_callback) - kbd_callback_method = f - - def main_loop(self): - - frame_count = 1 - start_time = glfwGetTime() - - running = True - while running: - - current_time = glfwGetTime() - - #Calculate and display FPS (frames per second) - if (current_time - start_time) > 1 or frame_count == 0: - frame_rate = frame_count / (current_time - start_time) - t = self.title + " (%d FPS)" % frame_rate - glfwSetWindowTitle(t) - start_time = current_time - frame_count = 0 - - frame_count = frame_count + 1 - - # Check if the ESC key was pressed or the window was closed - running = ((not glfwGetKey(GLFW_KEY_ESC)) - and glfwGetWindowParam(GLFW_OPENED)) - - self.update() - self.render() - - glfwSwapBuffers() - - - glfwTerminate() - - property window_title: - def __set__(self, title): self.title = title - - property time: - def __get__(self): return glfwGetTime() - def __set__(self, t): glfwSetTime(t) \ No newline at end of file diff --git a/python/framework/gl.pxd b/python/framework/gl.pxd deleted file mode 100644 index c1922fb..0000000 --- a/python/framework/gl.pxd +++ /dev/null @@ -1,1153 +0,0 @@ -# OpenGL Declarations -# -# Copyright (C) 2006,2007,2008 PySoy Group -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see http://www.gnu.org/licenses - -cdef extern from "GL/glew.h" : - ctypedef enum: - # Boolean Values - GL_FALSE - GL_TRUE - - # Data types - GL_BYTE - GL_UNSIGNED_BYTE - GL_SHORT - GL_UNSIGNED_SHORT - GL_INT - GL_UNSIGNED_INT - GL_FLOAT - GL_2_BYTES - GL_3_BYTES - GL_4_BYTES - GL_DOUBLE - - # Primitives - GL_POINTS - GL_LINES - GL_LINE_LOOP - GL_LINE_STRIP - GL_TRIANGLES - GL_TRIANGLE_STRIP - GL_TRIANGLE_FAN - GL_QUADS - GL_QUAD_STRIP - GL_POLYGON - - # Vertex Arrays - GL_VERTEX_ARRAY - GL_NORMAL_ARRAY - GL_COLOR_ARRAY - GL_INDEX_ARRAY - GL_TEXTURE_COORD_ARRAY - GL_EDGE_FLAG_ARRAY - GL_VERTEX_ARRAY_SIZE - GL_VERTEX_ARRAY_TYPE - GL_VERTEX_ARRAY_STRIDE - GL_NORMAL_ARRAY_TYPE - GL_NORMAL_ARRAY_STRIDE - GL_COLOR_ARRAY_SIZE - GL_COLOR_ARRAY_TYPE - GL_COLOR_ARRAY_STRIDE - GL_INDEX_ARRAY_TYPE - GL_INDEX_ARRAY_STRIDE - GL_TEXTURE_COORD_ARRAY_SIZE - GL_TEXTURE_COORD_ARRAY_TYPE - GL_TEXTURE_COORD_ARRAY_STRIDE - GL_EDGE_FLAG_ARRAY_STRIDE - GL_VERTEX_ARRAY_POINTER - GL_NORMAL_ARRAY_POINTER - GL_COLOR_ARRAY_POINTER - GL_INDEX_ARRAY_POINTER - GL_TEXTURE_COORD_ARRAY_POINTER - GL_EDGE_FLAG_ARRAY_POINTER - - # Vertex Buffer Objects - GL_BUFFER_SIZE_ARB - GL_BUFFER_USAGE_ARB - GL_ARRAY_BUFFER_ARB - GL_ELEMENT_ARRAY_BUFFER_ARB - GL_ARRAY_BUFFER_BINDING_ARB - GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB - GL_VERTEX_ARRAY_BUFFER_BINDING_ARB - GL_NORMAL_ARRAY_BUFFER_BINDING_ARB - GL_COLOR_ARRAY_BUFFER_BINDING_ARB - GL_INDEX_ARRAY_BUFFER_BINDING_ARB - GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB - GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB - GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB - GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB - GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB - GL_READ_ONLY_ARB - GL_WRITE_ONLY_ARB - GL_READ_WRITE_ARB - GL_BUFFER_ACCESS_ARB - GL_BUFFER_MAPPED_ARB - GL_BUFFER_MAP_POINTER_ARB - GL_STREAM_DRAW_ARB - GL_STREAM_READ_ARB - GL_STREAM_COPY_ARB - GL_STATIC_DRAW_ARB - GL_STATIC_READ_ARB - GL_STATIC_COPY_ARB - GL_DYNAMIC_DRAW_ARB - GL_DYNAMIC_READ_ARB - GL_DYNAMIC_COPY_ARB - - # Matrix Mode - GL_MATRIX_MODE - GL_MODELVIEW - GL_PROJECTION - GL_TEXTURE - - # Points - GL_POINT_SMOOTH - GL_POINT_SIZE - GL_POINT_SIZE_GRANULARITY - GL_POINT_SIZE_RANGE - - # Lines - GL_LINE_SMOOTH - GL_LINE_STIPPLE - GL_LINE_STIPPLE_PATTERN - GL_LINE_STIPPLE_REPEAT - GL_LINE_WIDTH - GL_LINE_WIDTH_GRANULARITY - GL_LINE_WIDTH_RANGE - - # Polygons - GL_POINT - GL_LINE - GL_FILL - GL_CW - GL_CCW - GL_FRONT - GL_BACK - GL_POLYGON_MODE - GL_POLYGON_SMOOTH - GL_POLYGON_STIPPLE - GL_EDGE_FLAG - GL_CULL_FACE - GL_CULL_FACE_MODE - GL_FRONT_FACE - GL_POLYGON_OFFSET_FACTOR - GL_POLYGON_OFFSET_UNITS - GL_POLYGON_OFFSET_POINT - GL_POLYGON_OFFSET_LINE - GL_POLYGON_OFFSET_FILL - - # Display Lists - GL_COMPILE - GL_COMPILE_AND_EXECUTE - GL_LIST_BASE - GL_LIST_INDEX - GL_LIST_MODE - - # Depth buffer - GL_NEVER - GL_LESS - GL_EQUAL - GL_LEQUAL - GL_GREATER - GL_NOTEQUAL - GL_GEQUAL - GL_ALWAYS - GL_DEPTH_TEST - GL_DEPTH_BITS - GL_DEPTH_CLEAR_VALUE - GL_DEPTH_FUNC - GL_DEPTH_RANGE - GL_DEPTH_WRITEMASK - GL_DEPTH_COMPONENT - - # Lighting - GL_LIGHTING - GL_LIGHT0 - GL_LIGHT1 - GL_LIGHT2 - GL_LIGHT3 - GL_LIGHT4 - GL_LIGHT5 - GL_LIGHT6 - GL_LIGHT7 - GL_SPOT_EXPONENT - GL_SPOT_CUTOFF - GL_CONSTANT_ATTENUATION - GL_LINEAR_ATTENUATION - GL_QUADRATIC_ATTENUATION - GL_AMBIENT - GL_DIFFUSE - GL_SPECULAR - GL_SHININESS - GL_EMISSION - GL_POSITION - GL_SPOT_DIRECTION - GL_AMBIENT_AND_DIFFUSE - GL_COLOR_INDEXES - GL_LIGHT_MODEL_TWO_SIDE - GL_LIGHT_MODEL_LOCAL_VIEWER - GL_LIGHT_MODEL_AMBIENT - GL_FRONT_AND_BACK - GL_SHADE_MODEL - GL_FLAT - GL_SMOOTH - GL_COLOR_MATERIAL - GL_COLOR_MATERIAL_FACE - GL_COLOR_MATERIAL_PARAMETER - GL_NORMALIZE - - # User clipping planes - GL_CLIP_PLANE0 - GL_CLIP_PLANE1 - GL_CLIP_PLANE2 - GL_CLIP_PLANE3 - GL_CLIP_PLANE4 - GL_CLIP_PLANE5 - - # Accumulation buffer - GL_ACCUM_RED_BITS - GL_ACCUM_GREEN_BITS - GL_ACCUM_BLUE_BITS - GL_ACCUM_ALPHA_BITS - GL_ACCUM_CLEAR_VALUE - GL_ACCUM - GL_ADD - GL_LOAD - GL_MULT - GL_RETURN - - # Alpha testing - GL_ALPHA_TEST - GL_ALPHA_TEST_REF - GL_ALPHA_TEST_FUNC - - # Blending - GL_BLEND - GL_BLEND_SRC - GL_BLEND_DST - GL_ZERO - GL_ONE - GL_SRC_COLOR - GL_ONE_MINUS_SRC_COLOR - GL_SRC_ALPHA - GL_ONE_MINUS_SRC_ALPHA - GL_DST_ALPHA - GL_ONE_MINUS_DST_ALPHA - GL_DST_COLOR - GL_ONE_MINUS_DST_COLOR - GL_SRC_ALPHA_SATURATE - - # Render Mode - GL_FEEDBACK - GL_RENDER - GL_SELECT - - # Feedback - GL_2D - GL_3D - GL_3D_COLOR - GL_3D_COLOR_TEXTURE - GL_4D_COLOR_TEXTURE - GL_POINT_TOKEN - GL_LINE_TOKEN - GL_LINE_RESET_TOKEN - GL_POLYGON_TOKEN - GL_BITMAP_TOKEN - GL_DRAW_PIXEL_TOKEN - GL_COPY_PIXEL_TOKEN - GL_PASS_THROUGH_TOKEN - GL_FEEDBACK_BUFFER_POINTER - GL_FEEDBACK_BUFFER_SIZE - GL_FEEDBACK_BUFFER_TYPE - - # Selection - GL_SELECTION_BUFFER_POINTER - GL_SELECTION_BUFFER_SIZE - - # Fog - GL_FOG - GL_FOG_MODE - GL_FOG_DENSITY - GL_FOG_COLOR - GL_FOG_INDEX - GL_FOG_START - GL_FOG_END - GL_LINEAR - GL_EXP - GL_EXP2 - - # Logic Ops - GL_LOGIC_OP - GL_INDEX_LOGIC_OP - GL_COLOR_LOGIC_OP - GL_LOGIC_OP_MODE - GL_CLEAR - GL_SET - GL_COPY - GL_COPY_INVERTED - GL_NOOP - GL_INVERT - GL_AND - GL_NAND - GL_OR - GL_NOR - GL_XOR - GL_EQUIV - GL_AND_REVERSE - GL_AND_INVERTED - GL_OR_REVERSE - GL_OR_INVERTED - - # Stencil - GL_STENCIL_BITS - GL_STENCIL_TEST - GL_STENCIL_CLEAR_VALUE - GL_STENCIL_FUNC - GL_STENCIL_VALUE_MASK - GL_STENCIL_FAIL - GL_STENCIL_PASS_DEPTH_FAIL - GL_STENCIL_PASS_DEPTH_PASS - GL_STENCIL_REF - GL_STENCIL_WRITEMASK - GL_STENCIL_INDEX - GL_KEEP - GL_REPLACE - GL_INCR - GL_DECR - - # Buffers, Pixel Drawing/Reading - GL_NONE - GL_LEFT - GL_RIGHT - #GL_FRONT - #GL_BACK - #GL_FRONT_AND_BACK - GL_FRONT_LEFT - GL_FRONT_RIGHT - GL_BACK_LEFT - GL_BACK_RIGHT - GL_AUX0 - GL_AUX1 - GL_AUX2 - GL_AUX3 - GL_COLOR_INDEX - GL_RED - GL_GREEN - GL_BLUE - GL_ALPHA - GL_LUMINANCE - GL_LUMINANCE_ALPHA - GL_ALPHA_BITS - GL_RED_BITS - GL_GREEN_BITS - GL_BLUE_BITS - GL_INDEX_BITS - GL_SUBPIXEL_BITS - GL_AUX_BUFFERS - GL_READ_BUFFER - GL_DRAW_BUFFER - GL_DOUBLEBUFFER - GL_STEREO - GL_BITMAP - GL_COLOR - GL_DEPTH - GL_STENCIL - GL_DITHER - GL_RGB - GL_RGBA - - # Implementation limits - GL_MAX_LIST_NESTING - GL_MAX_EVAL_ORDER - GL_MAX_LIGHTS - GL_MAX_CLIP_PLANES - GL_MAX_TEXTURE_SIZE - GL_MAX_PIXEL_MAP_TABLE - GL_MAX_ATTRIB_STACK_DEPTH - GL_MAX_MODELVIEW_STACK_DEPTH - GL_MAX_NAME_STACK_DEPTH - GL_MAX_PROJECTION_STACK_DEPTH - GL_MAX_TEXTURE_STACK_DEPTH - GL_MAX_VIEWPORT_DIMS - GL_MAX_CLIENT_ATTRIB_STACK_DEPTH - - # Gets - GL_ATTRIB_STACK_DEPTH - GL_CLIENT_ATTRIB_STACK_DEPTH - GL_COLOR_CLEAR_VALUE - GL_COLOR_WRITEMASK - GL_CURRENT_INDEX - GL_CURRENT_COLOR - GL_CURRENT_NORMAL - GL_CURRENT_RASTER_COLOR - GL_CURRENT_RASTER_DISTANCE - GL_CURRENT_RASTER_INDEX - GL_CURRENT_RASTER_POSITION - GL_CURRENT_RASTER_TEXTURE_COORDS - GL_CURRENT_RASTER_POSITION_VALID - GL_CURRENT_TEXTURE_COORDS - GL_INDEX_CLEAR_VALUE - GL_INDEX_MODE - GL_INDEX_WRITEMASK - GL_MODELVIEW_MATRIX - GL_MODELVIEW_STACK_DEPTH - GL_NAME_STACK_DEPTH - GL_PROJECTION_MATRIX - GL_PROJECTION_STACK_DEPTH - GL_RENDER_MODE - GL_RGBA_MODE - GL_TEXTURE_MATRIX - GL_TEXTURE_STACK_DEPTH - GL_VIEWPORT - - # Evaluators - GL_AUTO_NORMAL - GL_MAP1_COLOR_4 - GL_MAP1_INDEX - GL_MAP1_NORMAL - GL_MAP1_TEXTURE_COORD_1 - GL_MAP1_TEXTURE_COORD_2 - GL_MAP1_TEXTURE_COORD_3 - GL_MAP1_TEXTURE_COORD_4 - GL_MAP1_VERTEX_3 - GL_MAP1_VERTEX_4 - GL_MAP2_COLOR_4 - GL_MAP2_INDEX - GL_MAP2_NORMAL - GL_MAP2_TEXTURE_COORD_1 - GL_MAP2_TEXTURE_COORD_2 - GL_MAP2_TEXTURE_COORD_3 - GL_MAP2_TEXTURE_COORD_4 - GL_MAP2_VERTEX_3 - GL_MAP2_VERTEX_4 - GL_MAP1_GRID_DOMAIN - GL_MAP1_GRID_SEGMENTS - GL_MAP2_GRID_DOMAIN - GL_MAP2_GRID_SEGMENTS - GL_COEFF - GL_ORDER - GL_DOMAIN - - # Hints - GL_PERSPECTIVE_CORRECTION_HINT - GL_POINT_SMOOTH_HINT - GL_LINE_SMOOTH_HINT - GL_POLYGON_SMOOTH_HINT - GL_FOG_HINT - GL_DONT_CARE - GL_FASTEST - GL_NICEST - - # Scissor box - GL_SCISSOR_BOX - GL_SCISSOR_TEST - - # Pixel Mode / Transfer - GL_MAP_COLOR - GL_MAP_STENCIL - GL_INDEX_SHIFT - GL_INDEX_OFFSET - GL_RED_SCALE - GL_RED_BIAS - GL_GREEN_SCALE - GL_GREEN_BIAS - GL_BLUE_SCALE - GL_BLUE_BIAS - GL_ALPHA_SCALE - GL_ALPHA_BIAS - GL_DEPTH_SCALE - GL_DEPTH_BIAS - GL_PIXEL_MAP_S_TO_S_SIZE - GL_PIXEL_MAP_I_TO_I_SIZE - GL_PIXEL_MAP_I_TO_R_SIZE - GL_PIXEL_MAP_I_TO_G_SIZE - GL_PIXEL_MAP_I_TO_B_SIZE - GL_PIXEL_MAP_I_TO_A_SIZE - GL_PIXEL_MAP_R_TO_R_SIZE - GL_PIXEL_MAP_G_TO_G_SIZE - GL_PIXEL_MAP_B_TO_B_SIZE - GL_PIXEL_MAP_A_TO_A_SIZE - GL_PIXEL_MAP_S_TO_S - GL_PIXEL_MAP_I_TO_I - GL_PIXEL_MAP_I_TO_R - GL_PIXEL_MAP_I_TO_G - GL_PIXEL_MAP_I_TO_B - GL_PIXEL_MAP_I_TO_A - GL_PIXEL_MAP_R_TO_R - GL_PIXEL_MAP_G_TO_G - GL_PIXEL_MAP_B_TO_B - GL_PIXEL_MAP_A_TO_A - GL_PACK_ALIGNMENT - GL_PACK_LSB_FIRST - GL_PACK_ROW_LENGTH - GL_PACK_SKIP_PIXELS - GL_PACK_SKIP_ROWS - GL_PACK_SWAP_BYTES - GL_UNPACK_ALIGNMENT - GL_UNPACK_LSB_FIRST - GL_UNPACK_ROW_LENGTH - GL_UNPACK_SKIP_PIXELS - GL_UNPACK_SKIP_ROWS - GL_UNPACK_SWAP_BYTES - GL_ZOOM_X - GL_ZOOM_Y - - # Texture mapping - GL_TEXTURE_ENV - GL_TEXTURE_ENV_MODE - GL_TEXTURE_1D - GL_TEXTURE_2D - GL_TEXTURE_WRAP_S - GL_TEXTURE_WRAP_T - GL_TEXTURE_MAG_FILTER - GL_TEXTURE_MIN_FILTER - GL_TEXTURE_ENV_COLOR - GL_TEXTURE_GEN_S - GL_TEXTURE_GEN_T - GL_TEXTURE_GEN_MODE - GL_TEXTURE_BORDER_COLOR - GL_TEXTURE_WIDTH - GL_TEXTURE_HEIGHT - GL_TEXTURE_BORDER - GL_TEXTURE_COMPONENTS - GL_TEXTURE_RED_SIZE - GL_TEXTURE_GREEN_SIZE - GL_TEXTURE_BLUE_SIZE - GL_TEXTURE_ALPHA_SIZE - GL_TEXTURE_LUMINANCE_SIZE - GL_TEXTURE_INTENSITY_SIZE - GL_NEAREST_MIPMAP_NEAREST - GL_NEAREST_MIPMAP_LINEAR - GL_LINEAR_MIPMAP_NEAREST - GL_LINEAR_MIPMAP_LINEAR - GL_OBJECT_LINEAR - GL_OBJECT_PLANE - GL_EYE_LINEAR - GL_EYE_PLANE - GL_SPHERE_MAP - GL_DECAL - GL_MODULATE - GL_NEAREST - GL_REPEAT - GL_CLAMP - GL_S - GL_T - GL_R - GL_Q - GL_TEXTURE_GEN_R - GL_TEXTURE_GEN_Q - - # Utility - GL_VENDOR - GL_RENDERER - GL_VERSION - GL_EXTENSIONS - - # Errors - GL_NO_ERROR - GL_INVALID_ENUM - GL_INVALID_VALUE - GL_INVALID_OPERATION - GL_STACK_OVERFLOW - GL_STACK_UNDERFLOW - GL_OUT_OF_MEMORY - - # glPush/PopAttrib bits - GL_CURRENT_BIT - GL_POINT_BIT - GL_LINE_BIT - GL_POLYGON_BIT - GL_POLYGON_STIPPLE_BIT - GL_PIXEL_MODE_BIT - GL_LIGHTING_BIT - GL_FOG_BIT - GL_DEPTH_BUFFER_BIT - GL_ACCUM_BUFFER_BIT - GL_STENCIL_BUFFER_BIT - GL_VIEWPORT_BIT - GL_TRANSFORM_BIT - GL_ENABLE_BIT - GL_COLOR_BUFFER_BIT - GL_HINT_BIT - GL_EVAL_BIT - GL_LIST_BIT - GL_TEXTURE_BIT - GL_SCISSOR_BIT - GL_ALL_ATTRIB_BITS - - ##### OpenGL 1.1 ##### - - GL_PROXY_TEXTURE_1D - GL_PROXY_TEXTURE_2D - GL_TEXTURE_PRIORITY - GL_TEXTURE_RESIDENT - GL_TEXTURE_BINDING_1D - GL_TEXTURE_BINDING_2D - GL_TEXTURE_INTERNAL_FORMAT - GL_ALPHA4 - GL_ALPHA8 - GL_ALPHA12 - GL_ALPHA16 - GL_LUMINANCE4 - GL_LUMINANCE8 - GL_LUMINANCE12 - GL_LUMINANCE16 - GL_LUMINANCE4_ALPHA4 - GL_LUMINANCE6_ALPHA2 - GL_LUMINANCE8_ALPHA8 - GL_LUMINANCE12_ALPHA4 - GL_LUMINANCE12_ALPHA12 - GL_LUMINANCE16_ALPHA16 - GL_INTENSITY - GL_INTENSITY4 - GL_INTENSITY8 - GL_INTENSITY12 - GL_INTENSITY16 - GL_R3_G3_B2 - GL_RGB4 - GL_RGB5 - GL_RGB8 - GL_RGB10 - GL_RGB12 - GL_RGB16 - GL_RGBA2 - GL_RGBA4 - GL_RGB5_A1 - GL_RGBA8 - GL_RGB10_A2 - GL_RGBA12 - GL_RGBA16 - GL_CLIENT_PIXEL_STORE_BIT - GL_CLIENT_VERTEX_ARRAY_BIT - GL_ALL_CLIENT_ATTRIB_BITS - GL_CLIENT_ALL_ATTRIB_BITS - - ##### OpenGL 1.2 ##### - - GL_RESCALE_NORMAL - GL_CLAMP_TO_EDGE - GL_MAX_ELEMENTS_VERTICES - GL_MAX_ELEMENTS_INDICES - GL_BGR - GL_BGRA - GL_UNSIGNED_BYTE_3_3_2 - GL_UNSIGNED_BYTE_2_3_3_REV - GL_UNSIGNED_SHORT_5_6_5 - GL_UNSIGNED_SHORT_5_6_5_REV - GL_UNSIGNED_SHORT_4_4_4_4 - GL_UNSIGNED_SHORT_4_4_4_4_REV - GL_UNSIGNED_SHORT_5_5_5_1 - GL_UNSIGNED_SHORT_1_5_5_5_REV - GL_UNSIGNED_INT_8_8_8_8 - GL_UNSIGNED_INT_8_8_8_8_REV - GL_UNSIGNED_INT_10_10_10_2 - GL_UNSIGNED_INT_2_10_10_10_REV - GL_LIGHT_MODEL_COLOR_CONTROL - GL_SINGLE_COLOR - GL_SEPARATE_SPECULAR_COLOR - GL_TEXTURE_MIN_LOD - GL_TEXTURE_MAX_LOD - GL_TEXTURE_BASE_LEVEL - GL_TEXTURE_MAX_LEVEL - GL_SMOOTH_POINT_SIZE_RANGE - GL_SMOOTH_POINT_SIZE_GRANULARITY - GL_SMOOTH_LINE_WIDTH_RANGE - GL_SMOOTH_LINE_WIDTH_GRANULARITY - GL_ALIASED_POINT_SIZE_RANGE - GL_ALIASED_LINE_WIDTH_RANGE - GL_PACK_SKIP_IMAGES - GL_PACK_IMAGE_HEIGHT - GL_UNPACK_SKIP_IMAGES - GL_UNPACK_IMAGE_HEIGHT - GL_TEXTURE_3D - GL_PROXY_TEXTURE_3D - GL_TEXTURE_DEPTH - GL_TEXTURE_WRAP_R - GL_MAX_3D_TEXTURE_SIZE - GL_TEXTURE_BINDING_3D - - # GL_ARB_imaging - GL_CONSTANT_COLOR - GL_ONE_MINUS_CONSTANT_COLOR - GL_CONSTANT_ALPHA - GL_ONE_MINUS_CONSTANT_ALPHA - GL_COLOR_TABLE - GL_POST_CONVOLUTION_COLOR_TABLE - GL_POST_COLOR_MATRIX_COLOR_TABLE - GL_PROXY_COLOR_TABLE - GL_PROXY_POST_CONVOLUTION_COLOR_TABLE - GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE - GL_COLOR_TABLE_SCALE - GL_COLOR_TABLE_BIAS - GL_COLOR_TABLE_FORMAT - GL_COLOR_TABLE_WIDTH - GL_COLOR_TABLE_RED_SIZE - GL_COLOR_TABLE_GREEN_SIZE - GL_COLOR_TABLE_BLUE_SIZE - GL_COLOR_TABLE_ALPHA_SIZE - GL_COLOR_TABLE_LUMINANCE_SIZE - GL_COLOR_TABLE_INTENSITY_SIZE - GL_CONVOLUTION_1D - GL_CONVOLUTION_2D - GL_SEPARABLE_2D - GL_CONVOLUTION_BORDER_MODE - GL_CONVOLUTION_FILTER_SCALE - GL_CONVOLUTION_FILTER_BIAS - GL_REDUCE - GL_CONVOLUTION_FORMAT - GL_CONVOLUTION_WIDTH - GL_CONVOLUTION_HEIGHT - GL_MAX_CONVOLUTION_WIDTH - GL_MAX_CONVOLUTION_HEIGHT - GL_POST_CONVOLUTION_RED_SCALE - GL_POST_CONVOLUTION_GREEN_SCALE - GL_POST_CONVOLUTION_BLUE_SCALE - GL_POST_CONVOLUTION_ALPHA_SCALE - GL_POST_CONVOLUTION_RED_BIAS - GL_POST_CONVOLUTION_GREEN_BIAS - GL_POST_CONVOLUTION_BLUE_BIAS - GL_POST_CONVOLUTION_ALPHA_BIAS - GL_CONSTANT_BORDER - GL_REPLICATE_BORDER - GL_CONVOLUTION_BORDER_COLOR - GL_COLOR_MATRIX - GL_COLOR_MATRIX_STACK_DEPTH - GL_MAX_COLOR_MATRIX_STACK_DEPTH - GL_POST_COLOR_MATRIX_RED_SCALE - GL_POST_COLOR_MATRIX_GREEN_SCALE - GL_POST_COLOR_MATRIX_BLUE_SCALE - GL_POST_COLOR_MATRIX_ALPHA_SCALE - GL_POST_COLOR_MATRIX_RED_BIAS - GL_POST_COLOR_MATRIX_GREEN_BIAS - GL_POST_COLOR_MATRIX_BLUE_BIAS - GL_POST_COLOR_MATRIX_ALPHA_BIAS - GL_HISTOGRAM - GL_PROXY_HISTOGRAM - GL_HISTOGRAM_WIDTH - GL_HISTOGRAM_FORMAT - GL_HISTOGRAM_RED_SIZE - GL_HISTOGRAM_GREEN_SIZE - GL_HISTOGRAM_BLUE_SIZE - GL_HISTOGRAM_ALPHA_SIZE - GL_HISTOGRAM_LUMINANCE_SIZE - GL_HISTOGRAM_SINK - GL_MINMAX - GL_MINMAX_FORMAT - GL_MINMAX_SINK - GL_TABLE_TOO_LARGE - GL_BLEND_EQUATION - GL_MIN - GL_MAX - GL_FUNC_ADD - GL_FUNC_SUBTRACT - GL_FUNC_REVERSE_SUBTRACT - GL_BLEND_COLOR - - ##### OpenGL 1.3 ##### - - # multitexture - GL_TEXTURE0 - GL_TEXTURE1 - GL_TEXTURE2 - GL_TEXTURE3 - GL_TEXTURE4 - GL_TEXTURE5 - GL_TEXTURE6 - GL_TEXTURE7 - GL_TEXTURE8 - GL_TEXTURE9 - GL_TEXTURE10 - GL_TEXTURE11 - GL_TEXTURE12 - GL_TEXTURE13 - GL_TEXTURE14 - GL_TEXTURE15 - GL_TEXTURE16 - GL_TEXTURE17 - GL_TEXTURE18 - GL_TEXTURE19 - GL_TEXTURE20 - GL_TEXTURE21 - GL_TEXTURE22 - GL_TEXTURE23 - GL_TEXTURE24 - GL_TEXTURE25 - GL_TEXTURE26 - GL_TEXTURE27 - GL_TEXTURE28 - GL_TEXTURE29 - GL_TEXTURE30 - GL_TEXTURE31 - GL_ACTIVE_TEXTURE - GL_CLIENT_ACTIVE_TEXTURE - GL_MAX_TEXTURE_UNITS - - # texture_cube_map - GL_NORMAL_MAP - GL_REFLECTION_MAP - GL_TEXTURE_CUBE_MAP - GL_TEXTURE_BINDING_CUBE_MAP - GL_TEXTURE_CUBE_MAP_POSITIVE_X - GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_PROXY_TEXTURE_CUBE_MAP - GL_MAX_CUBE_MAP_TEXTURE_SIZE - - # texture_compression - GL_COMPRESSED_ALPHA - GL_COMPRESSED_LUMINANCE - GL_COMPRESSED_LUMINANCE_ALPHA - GL_COMPRESSED_INTENSITY - GL_COMPRESSED_RGB - GL_COMPRESSED_RGBA - GL_TEXTURE_COMPRESSION_HINT - GL_TEXTURE_COMPRESSED_IMAGE_SIZE - GL_TEXTURE_COMPRESSED - GL_NUM_COMPRESSED_TEXTURE_FORMATS - GL_COMPRESSED_TEXTURE_FORMATS - - # multisample - GL_MULTISAMPLE - GL_SAMPLE_ALPHA_TO_COVERAGE - GL_SAMPLE_ALPHA_TO_ONE - GL_SAMPLE_COVERAGE - GL_SAMPLE_BUFFERS - GL_SAMPLES - GL_SAMPLE_COVERAGE_VALUE - GL_SAMPLE_COVERAGE_INVERT - GL_MULTISAMPLE_BIT - - # transpose_matrix - GL_TRANSPOSE_MODELVIEW_MATRIX - GL_TRANSPOSE_PROJECTION_MATRIX - GL_TRANSPOSE_TEXTURE_MATRIX - GL_TRANSPOSE_COLOR_MATRIX - - # texture_env_combine - GL_COMBINE - GL_COMBINE_RGB - GL_COMBINE_ALPHA - GL_SOURCE0_RGB - GL_SOURCE1_RGB - GL_SOURCE2_RGB - GL_SOURCE0_ALPHA - GL_SOURCE1_ALPHA - GL_SOURCE2_ALPHA - GL_OPERAND0_RGB - GL_OPERAND1_RGB - GL_OPERAND2_RGB - GL_OPERAND0_ALPHA - GL_OPERAND1_ALPHA - GL_OPERAND2_ALPHA - GL_RGB_SCALE - GL_ADD_SIGNED - GL_INTERPOLATE - GL_SUBTRACT - GL_CONSTANT - GL_PRIMARY_COLOR - GL_PREVIOUS - - # texture_env_dot3 - GL_DOT3_RGB - GL_DOT3_RGBA - - # texture_border_clamp - GL_CLAMP_TO_BORDER - - - # GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) - GL_TEXTURE0_ARB - GL_TEXTURE1_ARB - GL_TEXTURE2_ARB - GL_TEXTURE3_ARB - GL_TEXTURE4_ARB - GL_TEXTURE5_ARB - GL_TEXTURE6_ARB - GL_TEXTURE7_ARB - GL_TEXTURE8_ARB - GL_TEXTURE9_ARB - GL_TEXTURE10_ARB - GL_TEXTURE11_ARB - GL_TEXTURE12_ARB - GL_TEXTURE13_ARB - GL_TEXTURE14_ARB - GL_TEXTURE15_ARB - GL_TEXTURE16_ARB - GL_TEXTURE17_ARB - GL_TEXTURE18_ARB - GL_TEXTURE19_ARB - GL_TEXTURE20_ARB - GL_TEXTURE21_ARB - GL_TEXTURE22_ARB - GL_TEXTURE23_ARB - GL_TEXTURE24_ARB - GL_TEXTURE25_ARB - GL_TEXTURE26_ARB - GL_TEXTURE27_ARB - GL_TEXTURE28_ARB - GL_TEXTURE29_ARB - GL_TEXTURE30_ARB - GL_TEXTURE31_ARB - GL_ACTIVE_TEXTURE_ARB - GL_CLIENT_ACTIVE_TEXTURE_ARB - GL_MAX_TEXTURE_UNITS_ARB - - # GLU quadratic flags - GLU_SMOOTH - GLU_FLAT - GLU_NONE - - # GLEW response flags - GLEW_OK - GLEW_NO_ERROR - GLEW_ERROR_NO_GL_VERSION - GLEW_ERROR_GL_VERSION_10_ONLY - GLEW_ERROR_GLX_VERSION_11_ONLY - - # GLEW rendering flags - GLEW_EXT_vertex_array - GLEW_ARB_vertex_buffer_object - - # Data types - ctypedef unsigned int GLenum - ctypedef unsigned char GLboolean - ctypedef unsigned int GLbitfield - ctypedef void GLvoid - ctypedef signed char GLbyte - ctypedef short GLshort - ctypedef int GLint - ctypedef unsigned char GLubyte - ctypedef unsigned short GLushort - ctypedef unsigned int GLuint - ctypedef int GLsizei - ctypedef float GLfloat - ctypedef float GLclampf - ctypedef double GLdouble - ctypedef double GLclampd - ctypedef char GLchar - ctypedef unsigned int GLhandleARB - ctypedef long GLintptrARB - ctypedef long GLsizeiptrARB - ctypedef void GLUquadricObj - - - # Miscellaneous - cdef void glClearIndex ( GLfloat c ) - cdef void glClearColor ( GLclampf, GLclampf, GLclampf, - GLclampf ) - cdef void glClear ( GLbitfield ) - cdef void glIndexMask ( GLuint ) - cdef void glColorMask ( GLboolean, GLboolean, GLboolean, - GLboolean ) - cdef void glAlphaFunc ( GLenum, GLclampf ) - cdef void glBlendFunc ( GLenum, GLenum ) - cdef void glLogicOp ( GLenum ) - cdef void glCullFace ( GLenum ) - cdef void glFrontFace ( GLenum ) - cdef void glPointSize ( GLfloat ) - cdef void glLineWidth ( GLfloat ) - cdef void glLineStipple ( GLint, GLushort ) - cdef void glPolygonMode ( GLenum, GLenum ) - cdef void glPolygonOffset ( GLfloat, GLfloat ) - cdef void glPolygonStipple ( GLubyte* ) - cdef void glGetPolygonStipple ( GLubyte* ) - cdef void glEdgeFlag ( GLboolean ) - cdef void glEdgeFlagv ( GLboolean* ) - cdef void glScissor ( GLint, GLint, GLsizei, GLsizei ) - cdef void glClipPlane ( GLenum, GLdouble* ) - cdef void glGetClipPlane ( GLenum plane, GLdouble *equation ) - cdef void glDrawBuffer ( GLenum ) - cdef void glReadBuffer ( GLenum ) - cdef void glEnable ( GLenum ) - cdef void glDisable ( GLenum ) - cdef GLboolean glIsEnabled ( GLenum cap ) - cdef void glEnableClientState ( GLenum ) - cdef void glDisableClientState ( GLenum ) - cdef void glGetBooleanv ( GLenum, GLboolean* ) - cdef void glGetDoublev ( GLenum, GLdouble* ) - cdef void glGetFloatv ( GLenum, GLfloat* ) - cdef void glGetIntegerv ( GLenum, GLint* ) - cdef void glPushAttrib ( GLbitfield ) - cdef void glPopAttrib ( ) - cdef void glPushClientAttrib ( GLbitfield ) # OpenGL 1.1 - cdef void glPopClientAttrib ( ) # OpenGL 1.1 - cdef GLint glRenderMode ( GLenum ) - cdef GLenum glGetError ( ) - cdef GLubyte *glGetString ( GLenum ) - cdef void glFinish ( ) - cdef void glFlush ( ) - cdef void glHint ( GLenum, GLenum ) - - # Depth Buffer - cdef void glClearDepth ( GLclampd ) - cdef void glDepthFunc ( GLenum ) - - # Transformations - cdef void glMatrixMode( GLenum ) - cdef void glOrtho( GLdouble left, GLdouble right, \ - GLdouble bottom, GLdouble top, \ - GLdouble near_val, GLdouble far_val ) - cdef void glViewport( GLint, GLint, GLsizei, GLsizei height ) - cdef void glPushMatrix() - cdef void glPopMatrix() - cdef void glLoadIdentity() - cdef void glLoadMatrixf( GLfloat* ) - cdef void glMultMatrixf( GLfloat* ) - cdef void glScalef( GLfloat, GLfloat, GLfloat ) - cdef void glTranslatef( GLfloat, GLfloat, GLfloat ) - - # Legacy Functions - cdef void glBegin( GLenum ) - cdef void glEnd() - cdef void glVertex2f( GLfloat, GLfloat y ) - cdef void glVertex3f( GLfloat, GLfloat, GLfloat z ) - cdef void glNormal3f( GLfloat, GLfloat, GLfloat z ) - cdef void glColor3f( GLfloat r, GLfloat g, GLfloat b ) - cdef void glColor3ub( GLubyte r, GLubyte g, GLubyte b ) - cdef void glColor4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) - - # Vertex Array Functions - cdef void glVertexPointer ( GLint, GLenum, GLsizei, GLvoid* ) - cdef void glNormalPointer ( GLenum, GLsizei, GLvoid* ) - cdef void glColorPointer ( GLint, GLenum, GLsizei, GLvoid* ) - cdef void glTexCoordPointer ( GLint, GLenum, GLsizei, GLvoid* ) - cdef void glDrawArrays ( GLenum, GLint, GLsizei ) - cdef void glDrawElements ( GLenum, GLsizei, GLenum, GLvoid* ) - - # VBO Functions - cdef void glBindBufferARB ( GLenum, GLuint ) - cdef void glDeleteBuffersARB ( GLsizei, GLuint* ) - cdef void glGenBuffersARB ( GLsizei, GLuint* ) - cdef void glBufferDataARB ( GLenum, GLsizeiptrARB, GLvoid*, - GLenum ) - cdef void glBufferSubDataARB ( GLenum, GLintptrARB, - GLsizeiptrARB, GLvoid* ) - cdef void glGetBufferSubDataARB ( GLenum, GLintptrARB, - GLsizeiptrARB, GLvoid* ) - cdef void *glMapBufferARB ( GLenum, GLenum ) - cdef void glGetBufferParameterivARB ( GLenum, GLenum, GLint* ) - cdef void glGetBufferPointervARB ( GLenum, GLenum, GLvoid** ) - cdef GLboolean glIsBufferARB ( GLuint ) - cdef GLboolean glUnmapBufferARB ( GLenum ) - - # Lighting - cdef void glShadeModel ( GLenum ) - cdef void glLightf ( GLenum, GLenum, GLfloat ) - cdef void glLighti ( GLenum, GLenum, GLint ) - cdef void glLightfv ( GLenum, GLenum, GLfloat* ) - cdef void glLightiv ( GLenum, GLenum, GLint* ) - cdef void glGetLightfv ( GLenum, GLenum, GLfloat* ) - cdef void glGetLightiv ( GLenum, GLenum, GLint* ) - cdef void glLightModelf ( GLenum, GLfloat ) - cdef void glLightModeli ( GLenum, GLint ) - cdef void glLightModelfv ( GLenum, GLfloat* ) - cdef void glLightModeliv ( GLenum, GLint* ) - cdef void glMaterialf ( GLenum, GLenum, GLfloat ) - cdef void glMateriali ( GLenum, GLenum, GLint ) - cdef void glMaterialfv ( GLenum, GLenum, GLfloat* ) - cdef void glMaterialiv ( GLenum, GLenum, GLint* ) - cdef void glGetMaterialfv ( GLenum, GLenum, GLfloat* ) - cdef void glGetMaterialiv ( GLenum, GLenum, GLint* ) - cdef void glColorMaterial ( GLenum, GLenum ) - - # Texture Mapping - cdef void glTexParameterf ( GLenum, GLenum, GLfloat ) - cdef void glTexParameteri ( GLenum, GLenum, GLint ) - cdef void glTexImage1D ( GLenum, GLint, GLint, GLsizei, GLint, GLenum, - GLenum, GLvoid* ) - cdef void glTexImage2D ( GLenum, GLint, GLint, GLsizei, GLsizei, GLint, - GLenum, GLenum, GLvoid* ) - cdef void glTexImage3D ( GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, - GLint, GLenum, GLenum, GLvoid* ) - cdef void glGenTextures ( GLsizei, GLuint* ) - cdef void glDeleteTextures ( GLsizei, GLuint* ) - cdef void glBindTexture ( GLenum, GLuint ) - cdef void glPrioritizeTextures( GLsizei, GLuint*, GLclampf* ) - cdef GLboolean glAreTexturesResident( GLsizei, GLuint*, GLboolean* ) - cdef GLboolean glIsTexture ( GLuint ) - cdef void glTexSubImage1D ( GLenum, GLint, GLint, GLsizei, GLenum, - GLenum, GLvoid* ) - cdef void glTexSubImage2D ( GLenum, GLint, GLint, GLint, GLsizei, GLsizei, - GLenum, GLenum, GLvoid* ) - cdef void glTexSubImage3D ( GLenum, GLint, GLint, GLint, GLint, GLsizei, - GLsizei, GLsizei, GLenum, GLenum, GLvoid* ) - cdef void glCopyTexImage1D ( GLenum, GLint, GLenum, GLint, GLint, - GLsizei, GLint ) - cdef void glCopyTexImage2D ( GLenum, GLint, GLenum, GLint, GLint, - GLsizei, GLsizei, GLint ) - cdef void glCopyTexSubImage1D( GLenum, GLint, GLint, GLint, GLint, GLsizei ) - cdef void glCopyTexSubImage2D( GLenum, GLint, GLint, GLint, GLint, GLint, - GLsizei, GLsizei ) - cdef void glCopyTexSubImage3D( GLenum, GLint, GLint, GLint, GLint, GLint, - GLint, GLsizei, GLsizei ) - - # GLU - cdef void gluPerspective( GLdouble, GLdouble, - GLdouble, GLdouble ) - cdef void gluSphere( GLUquadricObj*, GLdouble, GLint, GLint ) - cdef void gluCylinder( GLUquadricObj*, GLdouble, GLdouble, GLdouble, - GLint, GLint ) - cdef GLUquadricObj* gluNewQuadric( ) - cdef void gluDeleteQuadric( GLUquadricObj* ) - cdef void gluQuadricNormals( GLUquadricObj*, GLenum ) - cdef void gluQuadricTexture( GLUquadricObj*, GLenum ) - - # GLEW - cdef GLenum glewInit ( ) - cdef GLboolean glewIsSupported ( char* ) - -cdef extern from "GL/glu.h": - - ctypedef enum: - - # TessCallback - GLU_TESS_BEGIN - GLU_BEGIN - GLU_TESS_VERTEX - GLU_VERTEX - GLU_TESS_END - GLU_END - GLU_TESS_ERROR - GLU_TESS_EDGE_FLAG - GLU_EDGE_FLAG - GLU_TESS_COMBINE - GLU_TESS_BEGIN_DATA - GLU_TESS_VERTEX_DATA - GLU_TESS_END_DATA - GLU_TESS_ERROR_DATA - GLU_TESS_EDGE_FLAG_DATA - GLU_TESS_COMBINE_DATA - - # TessProperty - GLU_TESS_WINDING_RULE - - # TessWinding - GLU_TESS_WINDING_NONZERO - - ctypedef struct GLUtesselator "GLUtesselator" - cdef GLUtesselator* gluNewTess () - ctypedef void (*_GLUfuncptr)() - cdef void gluTessCallback (GLUtesselator*, GLenum, _GLUfuncptr) - cdef void gluTessNormal (GLUtesselator*, GLdouble, GLdouble, GLdouble) - cdef void gluTessProperty (GLUtesselator*, GLenum, GLdouble) - cdef void gluTessBeginPolygon (GLUtesselator*, GLvoid*) - cdef void gluTessBeginContour (GLUtesselator*) - cdef void gluTessVertex (GLUtesselator*, GLdouble *, GLvoid*) - cdef void gluTessEndContour (GLUtesselator*) - cdef void gluTessEndPolygon (GLUtesselator*) \ No newline at end of file diff --git a/python/framework/glfw.pxd b/python/framework/glfw.pxd deleted file mode 100644 index 9c98436..0000000 --- a/python/framework/glfw.pxd +++ /dev/null @@ -1,70 +0,0 @@ -# GLFW Declarations -# Copyright 2009 Mason Green & Tom Novelli -# -# This file is part of OpenMelee. -# -# OpenMelee is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# any later version. -# -# OpenMelee is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with OpenMelee. If not, see . - -cdef extern from "GL/glfw.h": - - ctypedef enum: - GLFW_WINDOW - GLFW_FULLSCREEN - GLFW_STICKY_KEYS - GLFW_OPENED - GLFW_KEY_ESC - GLFW_PRESS - - # Function pointer types - ctypedef void (__stdcall * GLFWwindowsizefun)(int, int) - ctypedef int (__stdcall * GLFWwindowclosefun)() - ctypedef void (__stdcall * GLFWwindowrefreshfun)() - ctypedef void (__stdcall * GLFWmousebuttonfun)(int, int) - ctypedef void (__stdcall * GLFWmouseposfun)(int, int) - ctypedef void (__stdcall * GLFWmousewheelfun)(int) - ctypedef void (__stdcall * GLFWkeyfun)(int, int) - ctypedef void (__stdcall * GLFWcharfun)(int, int) - ctypedef void (__stdcall * GLFWthreadfun)() - - int glfwInit() - void glfwTerminate() - void glfwSetWindowTitle(char *title) - int glfwOpenWindow( int width, int height, - int redbits, int greenbits, int bluebits, int alphabits, - int depthbits, int stencilbits, int mode ) - void glfwSwapInterval( int interval ) - void glfwSwapBuffers() - void glfwEnable( int token ) - int glfwGetWindowParam( int param ) - int glfwGetKey( int key ) - int glfwGetWindowParam( int param ) - void glfwGetWindowSize( int *width, int *height ) - double glfwGetTime() - void glfwSetTime(double time) - - # Input handling - void glfwPollEvents() - void glfwWaitEvents() - int glfwGetKey( int key ) - int glfwGetMouseButton( int button ) - void glfwGetMousePos( int *xpos, int *ypos ) - void glfwSetMousePos( int xpos, int ypos ) - int glfwGetMouseWheel() - void glfwSetMouseWheel( int pos ) - void glfwSetKeyCallback(GLFWkeyfun cbfun) - void glfwSetCharCallback( GLFWcharfun cbfun ) - void glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun ) - void glfwSetMousePosCallback( GLFWmouseposfun cbfun ) - void glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun ) - \ No newline at end of file diff --git a/python/framework/polydecomp.pxi b/python/framework/polydecomp.pxi deleted file mode 100644 index c2add2f..0000000 --- a/python/framework/polydecomp.pxi +++ /dev/null @@ -1,158 +0,0 @@ -## -## Ported from PolyDeomp by Mark Bayazit -## http://mnbayazit.com/406/bayazit -## -from sys import float_info - -cdef extern from 'predicates.h': - double orient2d(double *pa, double *pb, double *pc) - -def make_ccw(list poly): - cdef int br = 0 - # find bottom right point - for i from 1 <= i < len(poly): - if poly[i][1] < poly[br][1] or (poly[i][1] == poly[br][1] and poly[i][0] > poly[br][0]): - br = i - # reverse poly if clockwise - if not left(at(poly, br - 1), at(poly, br), at(poly, br + 1)): - poly.reverse() - -cpdef list decompose_poly(list poly, list polys): - - cdef list upperInt = [], lowerInt = [], p = [], closestVert = [] - cdef float upperDist, lowerDist, d, closestDist - cdef int upper_index, lower_index, closest_index - cdef list lower_poly = [], upper_poly = [] - - for i from 0 <= i < len(poly): - if is_reflex(poly, i): - upperDist = lowerDist = float_info.max - for j from 0 <= j < len(poly): - if left(at(poly, i - 1), at(poly, i), at(poly, j)) and rightOn(at(poly, i - 1), at(poly, i), at(poly, j - 1)): - # if line intersects with an edge - # find the point of intersection - p = intersection(at(poly, i - 1), at(poly, i), at(poly, j), at(poly, j - 1)) - if right(at(poly, i + 1), at(poly, i), p): - # make sure it's inside the poly - d = sqdist(poly[i], p) - if d < lowerDist: - # keep only the closest intersection - lowerDist = d - lowerInt = p - lower_index = j - if left(at(poly, i + 1), at(poly, i), at(poly, j + 1)) and rightOn(at(poly, i + 1), at(poly, i), at(poly, j)): - p = intersection(at(poly, i + 1), at(poly, i), at(poly, j), at(poly, j + 1)) - if left(at(poly, i - 1), at(poly, i), p): - d = sqdist(poly[i], p) - if d < upperDist: - upperDist = d - upperInt = p - upper_index = j - - # if there are no vertices to connect to, choose a point in the middle - if lower_index == (upper_index + 1) % len(poly): - p[0] = (lowerInt[0] + upperInt[0]) * 0.5 - p[1] = (lowerInt[1] + upperInt[1]) * 0.5 - - if i < upper_index: - lower_poly.extend(poly[i:upper_index+1]) - lower_poly.append(p) - upper_poly.append(p) - if lower_index != 0: - upper_poly.extend(poly[lower_index:]) - upper_poly.extend(poly[:i+1]) - else: - if i != 0: - lower_poly.extend(poly[i:]) - lower_poly.extend(poly[:upper_index+1]) - lower_poly.append(p) - upper_poly.append(p) - upper_poly.extend(poly[lower_index:i+1]) - else: - - # connect to the closest point within the triangle - - if lower_index > upper_index: - upper_index += len(poly) - - closestDist = float_info.max - for j from lower_index <= j <= upper_index: - if leftOn(at(poly, i - 1), at(poly, i), at(poly, j)) and rightOn(at(poly, i + 1), at(poly, i), at(poly, j)): - d = sqdist(at(poly, i), at(poly, j)) - if d < closestDist: - closestDist = d - closestVert = at(poly, j) - closest_index = j % len(poly) - - if i < closest_index: - lower_poly.extend(poly[i:closest_index+1]) - if closest_index != 0: - upper_poly.extend(poly[closest_index:]) - upper_poly.extend(poly[:i+1]) - else: - if i != 0: - lower_poly.extend(poly[i:]) - lower_poly.extend(poly[:closest_index+1]) - upper_poly.extend(poly[closest_index:i+1]) - - # solve smallest poly first - if len(lower_poly) < len(upper_poly): - decompose_poly(lower_poly, polys) - decompose_poly(upper_poly, polys) - else: - decompose_poly(upper_poly, polys) - decompose_poly(lower_poly, polys) - return - - polys.append(poly) - -cdef list intersection(list p1, list p2, list q1, list q2): - cdef double pqx, pqy, bax, bay, t - pqx = p1[0] - p2[0] - pqy = p1[1] - p2[1] - t = pqy*(q1[0]-p2[0]) - pqx*(q1[1]-p2[1]) - t /= pqx*(q2[1]-q1[1]) - pqy*(q2[0]-q1[0]) - bax = t*(q2[0]-q1[0]) + q1[0] - bay = t*(q2[1]-q1[1]) + q1[1] - return [bax, bay] - -cdef bool eq(float a, float b): - return abs(a - b) <= 1e-8 - -cdef list at(list v, int i): - return v[i%len(v)] - -cdef float area(list a, list b, list c): - return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1]))) - -cdef bool left(list a, list b, list c): - cdef double *x = [a[0], a[1]] - cdef double *y = [b[0], b[1]] - cdef double *z = [c[0], c[1]] - return orient2d(x, y, z) > 0.0 - -cdef bool leftOn(list a, list b, list c): - cdef double *x = [a[0], a[1]] - cdef double *y = [b[0], b[1]] - cdef double *z = [c[0], c[1]] - return orient2d(x, y, z) >= 0.0 - -cdef bool right(list a, list b, list c): - cdef double *x = [a[0], a[1]] - cdef double *y = [b[0], b[1]] - cdef double *z = [c[0], c[1]] - return orient2d(x, y, z) < 0.0 - -cdef bool rightOn(list a, list b, list c): - cdef double *x = [a[0], a[1]] - cdef double *y = [b[0], b[1]] - cdef double *z = [c[0], c[1]] - return orient2d(x, y, z) <= 0.0 - -cdef float sqdist(list a, list b): - cdef float dx = b[0] - a[0] - cdef float dy = b[1] - a[1] - return dx * dx + dy * dy - -cdef bool is_reflex(list poly, int i): - return right(at(poly, i - 1), at(poly, i), at(poly, i + 1)) \ No newline at end of file diff --git a/python/framework/predicates.c b/python/framework/predicates.c deleted file mode 100644 index e0a6533..0000000 --- a/python/framework/predicates.c +++ /dev/null @@ -1,4262 +0,0 @@ -/*****************************************************************************/ -/* */ -/* Routines for Arbitrary Precision Floating-point Arithmetic */ -/* and Fast Robust Geometric Predicates */ -/* (predicates.c) */ -/* */ -/* May 18, 1996 */ -/* */ -/* Placed in the public domain by */ -/* Jonathan Richard Shewchuk */ -/* School of Computer Science */ -/* Carnegie Mellon University */ -/* 5000 Forbes Avenue */ -/* Pittsburgh, Pennsylvania 15213-3891 */ -/* jrs@cs.cmu.edu */ -/* */ -/* This file contains C implementation of algorithms for exact addition */ -/* and multiplication of floating-point numbers, and predicates for */ -/* robustly performing the orientation and incircle tests used in */ -/* computational geometry. The algorithms and underlying theory are */ -/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ -/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ -/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ -/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ -/* Discrete & Computational Geometry.) */ -/* */ -/* This file, the paper listed above, and other information are available */ -/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* Using this code: */ -/* */ -/* First, read the short or long version of the paper (from the Web page */ -/* above). */ -/* */ -/* Be sure to call exactinit() once, before calling any of the arithmetic */ -/* functions or geometric predicates. Also be sure to turn on the */ -/* optimizer when compiling this file. */ -/* */ -/* */ -/* Several geometric predicates are defined. Their parameters are all */ -/* points. Each point is an array of two or three floating-point */ -/* numbers. The geometric predicates, described in the papers, are */ -/* */ -/* orient2d(pa, pb, pc) */ -/* orient2dfast(pa, pb, pc) */ -/* orient3d(pa, pb, pc, pd) */ -/* orient3dfast(pa, pb, pc, pd) */ -/* incircle(pa, pb, pc, pd) */ -/* incirclefast(pa, pb, pc, pd) */ -/* insphere(pa, pb, pc, pd, pe) */ -/* inspherefast(pa, pb, pc, pd, pe) */ -/* */ -/* Those with suffix "fast" are approximate, non-robust versions. Those */ -/* without the suffix are adaptive precision, robust versions. There */ -/* are also versions with the suffices "exact" and "slow", which are */ -/* non-adaptive, exact arithmetic versions, which I use only for timings */ -/* in my arithmetic papers. */ -/* */ -/* */ -/* An expansion is represented by an array of floating-point numbers, */ -/* sorted from smallest to largest magnitude (possibly with interspersed */ -/* zeros). The length of each expansion is stored as a separate integer, */ -/* and each arithmetic function returns an integer which is the length */ -/* of the expansion it created. */ -/* */ -/* Several arithmetic functions are defined. Their parameters are */ -/* */ -/* e, f Input expansions */ -/* elen, flen Lengths of input expansions (must be >= 1) */ -/* h Output expansion */ -/* b Input scalar */ -/* */ -/* The arithmetic functions are */ -/* */ -/* grow_expansion(elen, e, b, h) */ -/* grow_expansion_zeroelim(elen, e, b, h) */ -/* expansion_sum(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim1(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim2(elen, e, flen, f, h) */ -/* fast_expansion_sum(elen, e, flen, f, h) */ -/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* linear_expansion_sum(elen, e, flen, f, h) */ -/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* scale_expansion(elen, e, b, h) */ -/* scale_expansion_zeroelim(elen, e, b, h) */ -/* compress(elen, e, h) */ -/* */ -/* All of these are described in the long version of the paper; some are */ -/* described in the short version. All return an integer that is the */ -/* length of h. Those with suffix _zeroelim perform zero elimination, */ -/* and are recommended over their counterparts. The procedure */ -/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ -/* processors that do not use the round-to-even tiebreaking rule) is */ -/* recommended over expansion_sum_zeroelim(). Each procedure has a */ -/* little note next to it (in the code below) that tells you whether or */ -/* not the output expansion may be the same array as one of the input */ -/* expansions. */ -/* */ -/* */ -/* If you look around below, you'll also find macros for a bunch of */ -/* simple unrolled arithmetic operations, and procedures for printing */ -/* expansions (commented out because they don't work with all C */ -/* compilers) and for generating random floating-point numbers whose */ -/* significand bits are all random. Most of the macros have undocumented */ -/* requirements that certain of their parameters should not be the same */ -/* variable; for safety, better to make sure all the parameters are */ -/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ -/* have questions. */ -/* */ -/*****************************************************************************/ - -#include -#include -#include -#include - -/* On some machines, the exact arithmetic routines might be defeated by the */ -/* use of internal extended precision floating-point registers. Sometimes */ -/* this problem can be fixed by defining certain values to be volatile, */ -/* thus forcing them to be stored to memory and rounded off. This isn't */ -/* a great solution, though, as it slows the arithmetic down. */ -/* */ -/* To try this out, write "#define INEXACT volatile" below. Normally, */ -/* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */ - -#define INEXACT /* Nothing */ -/* #define INEXACT volatile */ - -#define REAL double /* float or double */ -#define REALPRINT doubleprint -#define REALRAND doublerand -#define NARROWRAND narrowdoublerand -#define UNIFORMRAND uniformdoublerand - -/* Which of the following two methods of finding the absolute values is */ -/* fastest is compiler-dependent. A few compilers can inline and optimize */ -/* the fabs() call; but most will incur the overhead of a function call, */ -/* which is disastrously slow. A faster way on IEEE machines might be to */ -/* mask the appropriate bit, but that's difficult to do in C. */ - -#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) -/* #define Absolute(a) fabs(a) */ - -/* Many of the operations are broken up into two pieces, a main part that */ -/* performs an approximate operation, and a "tail" that computes the */ -/* roundoff error of that operation. */ -/* */ -/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ -/* Split(), and Two_Product() are all implemented as described in the */ -/* reference. Each of these macros requires certain variables to be */ -/* defined in the calling routine. The variables `bvirt', `c', `abig', */ -/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ -/* they store the result of an operation that may incur roundoff error. */ -/* The input parameter `x' (or the highest numbered `x_' parameter) must */ -/* also be declared `INEXACT'. */ - -#define Fast_Two_Sum_Tail(a, b, x, y) \ - bvirt = x - a; \ - y = b - bvirt - -#define Fast_Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Fast_Two_Sum_Tail(a, b, x, y) - -#define Fast_Two_Diff_Tail(a, b, x, y) \ - bvirt = a - x; \ - y = bvirt - b - -#define Fast_Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Fast_Two_Diff_Tail(a, b, x, y) - -#define Two_Sum_Tail(a, b, x, y) \ - bvirt = (REAL) (x - a); \ - avirt = x - bvirt; \ - bround = b - bvirt; \ - around = a - avirt; \ - y = around + bround - -#define Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Two_Sum_Tail(a, b, x, y) - -#define Two_Diff_Tail(a, b, x, y) \ - bvirt = (REAL) (a - x); \ - avirt = x + bvirt; \ - bround = bvirt - b; \ - around = a - avirt; \ - y = around + bround - -#define Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Two_Diff_Tail(a, b, x, y) - -#define Split(a, ahi, alo) \ - c = (REAL) (splitter * a); \ - abig = (REAL) (c - a); \ - ahi = c - abig; \ - alo = a - ahi - -#define Two_Product_Tail(a, b, x, y) \ - Split(a, ahi, alo); \ - Split(b, bhi, blo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -#define Two_Product(a, b, x, y) \ - x = (REAL) (a * b); \ - Two_Product_Tail(a, b, x, y) - -/* Two_Product_Presplit() is Two_Product() where one of the inputs has */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_Presplit(a, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - Split(a, ahi, alo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Square() can be done more quickly than Two_Product(). */ - -#define Square_Tail(a, x, y) \ - Split(a, ahi, alo); \ - err1 = x - (ahi * ahi); \ - err3 = err1 - ((ahi + ahi) * alo); \ - y = (alo * alo) - err3 - -#define Square(a, x, y) \ - x = (REAL) (a * a); \ - Square_Tail(a, x, y) - -/* Macros for summing expansions of various fixed lengths. These are all */ -/* unrolled versions of Expansion_Sum(). */ - -#define Two_One_Sum(a1, a0, b, x2, x1, x0) \ - Two_Sum(a0, b , _i, x0); \ - Two_Sum(a1, _i, x2, x1) - -#define Two_One_Diff(a1, a0, b, x2, x1, x0) \ - Two_Diff(a0, b , _i, x0); \ - Two_Sum( a1, _i, x2, x1) - -#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b0, _j, _0, x0); \ - Two_One_Sum(_j, _0, b1, x3, x2, x1) - -#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Diff(a1, a0, b0, _j, _0, x0); \ - Two_One_Diff(_j, _0, b1, x3, x2, x1) - -#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b , _j, x1, x0); \ - Two_One_Sum(a3, a2, _j, x4, x3, x2) - -#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ - Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) - -#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ - x1, x0) \ - Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ - Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) - -#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ - x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ - Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) - -#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ - x6, x5, x4, x3, x2, x1, x0) \ - Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ - _1, _0, x0); \ - Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ - x3, x2, x1) - -#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ - x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ - Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ - _2, _1, _0, x1, x0); \ - Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ - x7, x6, x5, x4, x3, x2) - -/* Macros for multiplying expansions of various fixed lengths. */ - -#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, x3, x2) - -#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, _i, x2); \ - Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x3); \ - Fast_Two_Sum(_j, _k, _i, x4); \ - Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x5); \ - Fast_Two_Sum(_j, _k, x7, x6) - -#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(a0, a0hi, a0lo); \ - Split(b0, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ - Split(a1, a1hi, a1lo); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, _1); \ - Fast_Two_Sum(_j, _k, _l, _2); \ - Split(b1, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ - Two_Sum(_1, _0, _k, x1); \ - Two_Sum(_2, _k, _j, _1); \ - Two_Sum(_l, _j, _m, _2); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _n, _0); \ - Two_Sum(_1, _0, _i, x2); \ - Two_Sum(_2, _i, _k, _1); \ - Two_Sum(_m, _k, _l, _2); \ - Two_Sum(_j, _n, _k, _0); \ - Two_Sum(_1, _0, _j, x3); \ - Two_Sum(_2, _j, _i, _1); \ - Two_Sum(_l, _i, _m, _2); \ - Two_Sum(_1, _k, _i, x4); \ - Two_Sum(_2, _i, _k, x5); \ - Two_Sum(_m, _k, x7, x6) - -/* An expansion of length two can be squared more quickly than finding the */ -/* product of two different expansions of length two, and the result is */ -/* guaranteed to have no more than six (rather than eight) components. */ - -#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ - Square(a0, _j, x0); \ - _0 = a0 + a0; \ - Two_Product(a1, _0, _k, _1); \ - Two_One_Sum(_k, _1, _j, _l, _2, x1); \ - Square(a1, _j, _1); \ - Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) - -REAL splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */ -REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ -/* A set of coefficients used to calculate maximum roundoff errors. */ -REAL resulterrbound; -REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; -REAL o3derrboundA, o3derrboundB, o3derrboundC; -REAL iccerrboundA, iccerrboundB, iccerrboundC; -REAL isperrboundA, isperrboundB, isperrboundC; - -/*****************************************************************************/ -/* */ -/* doubleprint() Print the bit representation of a double. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void doubleprint(number) -double number; -{ - unsigned long long no; - unsigned long long sign, expo; - int exponent; - int i, bottomi; - - no = *(unsigned long long *) &number; - sign = no & 0x8000000000000000ll; - expo = (no >> 52) & 0x7ffll; - exponent = (int) expo; - exponent = exponent - 1023; - if (sign) { - printf("-"); - } else { - printf(" "); - } - if (exponent == -1023) { - printf( - "0.0000000000000000000000000000000000000000000000000000_ ( )"); - } else { - printf("1."); - bottomi = -1; - for (i = 0; i < 52; i++) { - if (no & 0x0008000000000000ll) { - printf("1"); - bottomi = i; - } else { - printf("0"); - } - no <<= 1; - } - printf("_%d (%d)", exponent, exponent - 1 - bottomi); - } -} -*/ - -/*****************************************************************************/ -/* */ -/* floatprint() Print the bit representation of a float. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void floatprint(number) -float number; -{ - unsigned no; - unsigned sign, expo; - int exponent; - int i, bottomi; - - no = *(unsigned *) &number; - sign = no & 0x80000000; - expo = (no >> 23) & 0xff; - exponent = (int) expo; - exponent = exponent - 127; - if (sign) { - printf("-"); - } else { - printf(" "); - } - if (exponent == -127) { - printf("0.00000000000000000000000_ ( )"); - } else { - printf("1."); - bottomi = -1; - for (i = 0; i < 23; i++) { - if (no & 0x00400000) { - printf("1"); - bottomi = i; - } else { - printf("0"); - } - no <<= 1; - } - printf("_%3d (%3d)", exponent, exponent - 1 - bottomi); - } -} -*/ - -/*****************************************************************************/ -/* */ -/* expansion_print() Print the bit representation of an expansion. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void expansion_print(elen, e) -int elen; -REAL *e; -{ - int i; - - for (i = elen - 1; i >= 0; i--) { - REALPRINT(e[i]); - if (i > 0) { - printf(" +\n"); - } else { - printf("\n"); - } - } -} -*/ - -/*****************************************************************************/ -/* */ -/* doublerand() Generate a double with random 53-bit significand and a */ -/* random exponent in [0, 511]. */ -/* */ -/*****************************************************************************/ - -double doublerand() -{ - double result; - double expo; - long a, b, c; - long i; - - a = rand(); - b = rand(); - c = rand(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} - -/*****************************************************************************/ -/* */ -/* narrowdoublerand() Generate a double with random 53-bit significand */ -/* and a random exponent in [0, 7]. */ -/* */ -/*****************************************************************************/ - -double narrowdoublerand() -{ - double result; - double expo; - long a, b, c; - long i; - - a = rand(); - b = rand(); - c = rand(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} - -/*****************************************************************************/ -/* */ -/* uniformdoublerand() Generate a double with random 53-bit significand. */ -/* */ -/*****************************************************************************/ - -double uniformdoublerand() -{ - double result; - long a, b; - - a = rand(); - b = rand(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - return result; -} - -/*****************************************************************************/ -/* */ -/* floatrand() Generate a float with random 24-bit significand and a */ -/* random exponent in [0, 63]. */ -/* */ -/*****************************************************************************/ - -float floatrand() -{ - float result; - float expo; - long a, c; - long i; - - a = rand(); - c = rand(); - result = (float) ((a - 1073741824) >> 6); - for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} - -/*****************************************************************************/ -/* */ -/* narrowfloatrand() Generate a float with random 24-bit significand and */ -/* a random exponent in [0, 7]. */ -/* */ -/*****************************************************************************/ - -float narrowfloatrand() -{ - float result; - float expo; - long a, c; - long i; - - a = rand(); - c = rand(); - result = (float) ((a - 1073741824) >> 6); - for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} - -/*****************************************************************************/ -/* */ -/* uniformfloatrand() Generate a float with random 24-bit significand. */ -/* */ -/*****************************************************************************/ - -float uniformfloatrand() -{ - float result; - long a; - - a = rand(); - result = (float) ((a - 1073741824) >> 6); - return result; -} - -/*****************************************************************************/ -/* */ -/* exactinit() Initialize the variables used for exact arithmetic. */ -/* */ -/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ -/* floating-point arithmetic. `epsilon' bounds the relative roundoff */ -/* error. It is used for floating-point error analysis. */ -/* */ -/* `splitter' is used to split floating-point numbers into two half- */ -/* length significands for exact multiplication. */ -/* */ -/* I imagine that a highly optimizing compiler might be too smart for its */ -/* own good, and somehow cause this routine to fail, if it pretends that */ -/* floating-point arithmetic is too much like real arithmetic. */ -/* */ -/* Don't change this routine unless you fully understand it. */ -/* */ -/*****************************************************************************/ - -void exactinit() -{ - REAL half; - REAL check, lastcheck; - int every_other; - - every_other = 1; - half = 0.5; - epsilon = 1.0; - splitter = 1.0; - check = 1.0; - /* Repeatedly divide `epsilon' by two until it is too small to add to */ - /* one without causing roundoff. (Also check if the sum is equal to */ - /* the previous sum, for machines that round up instead of using exact */ - /* rounding. Not that this library will work on such machines anyway. */ - do { - lastcheck = check; - epsilon *= half; - if (every_other) { - splitter *= 2.0; - } - every_other = !every_other; - check = 1.0 + epsilon; - } while ((check != 1.0) && (check != lastcheck)); - splitter += 1.0; - - /* Error bounds for orientation and incircle tests. */ - resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; - ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; - ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; - ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; - o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; - o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; - o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; - iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; - iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; - iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; - isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; - isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; - isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; -} - -/*****************************************************************************/ -/* */ -/* grow_expansion() Add a scalar to an expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion(elen, e, b, h) /* e and h can be the same. */ -int elen; -REAL *e; -REAL b; -REAL *h; -{ - REAL Q; - INEXACT REAL Qnew; - int eindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, h[eindex]); - Q = Qnew; - } - h[eindex] = Q; - return eindex + 1; -} - -/*****************************************************************************/ -/* */ -/* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ -/* zero components from the output expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion_zeroelim(elen, e, b, h) /* e and h can be the same. */ -int elen; -REAL *e; -REAL b; -REAL *h; -{ - REAL Q, hh; - INEXACT REAL Qnew; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - hindex = 0; - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum(elen, e, flen, f, h) -/* e and h can be the same, but f and h cannot. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q; - INEXACT REAL Qnew; - int findex, hindex, hlast; - REAL hnow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim1(elen, e, flen, f, h) -/* e and h can be the same, but f and h cannot. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q; - INEXACT REAL Qnew; - int index, findex, hindex, hlast; - REAL hnow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - hindex = -1; - for (index = 0; index <= hlast; index++) { - hnow = h[index]; - if (hnow != 0.0) { - h[++hindex] = hnow; - } - } - if (hindex == -1) { - return 1; - } else { - return hindex + 1; - } -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim2(elen, e, flen, f, h) -/* e and h can be the same, but f and h cannot. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q, hh; - INEXACT REAL Qnew; - int eindex, findex, hindex, hlast; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - hindex = 0; - Q = f[0]; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - hindex = 0; - Q = f[findex]; - for (eindex = 0; eindex <= hlast; eindex++) { - enow = h[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum(elen, e, flen, f, h) /* h cannot be e or f. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q; - INEXACT REAL Qnew; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, h[0]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, h[0]); - fnow = f[++findex]; - } - Q = Qnew; - hindex = 1; - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - } - Q = Qnew; - hindex++; - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - Q = Qnew; - hindex++; - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - Q = Qnew; - hindex++; - } - h[hindex] = Q; - return hindex + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum_zeroelim(elen, e, flen, f, h) /* h cannot be e or f. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q; - INEXACT REAL Qnew; - INEXACT REAL hh; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum(elen, e, flen, f, h) /* h cannot be e or f. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q, q; - INEXACT REAL Qnew; - INEXACT REAL R; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - REAL g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (hindex = 0; hindex < elen + flen - 2; hindex++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, h[hindex]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, h[hindex]); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - } - h[hindex] = q; - h[hindex + 1] = Q; - return hindex + 2; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum_zeroelim(elen, e, flen, f, h)/* h cannot be e or f. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -{ - REAL Q, q, hh; - INEXACT REAL Qnew; - INEXACT REAL R; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - int count; - REAL enow, fnow; - REAL g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - hindex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (count = 2; count < elen + flen; count++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, hh); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - if (q != 0) { - h[hindex++] = q; - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion() Multiply an expansion by a scalar. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion(elen, e, b, h) /* e and h cannot be the same. */ -int elen; -REAL *e; -REAL b; -REAL *h; -{ - INEXACT REAL Q; - INEXACT REAL sum; - INEXACT REAL product1; - REAL product0; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); - hindex = 1; - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, h[hindex]); - hindex++; - Two_Sum(product1, sum, Q, h[hindex]); - hindex++; - } - h[hindex] = Q; - return elen + elen; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ -/* eliminating zero components from the */ -/* output expansion. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion_zeroelim(elen, e, b, h) /* e and h cannot be the same. */ -int elen; -REAL *e; -REAL b; -REAL *h; -{ - INEXACT REAL Q, sum; - REAL hh; - INEXACT REAL product1; - REAL product0; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); - hindex = 0; - if (hh != 0) { - h[hindex++] = hh; - } - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, hh); - if (hh != 0) { - h[hindex++] = hh; - } - Fast_Two_Sum(product1, sum, Q, hh); - if (hh != 0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* compress() Compress an expansion. */ -/* */ -/* See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), then any nonoverlapping expansion is converted to a */ -/* nonadjacent expansion. */ -/* */ -/*****************************************************************************/ - -int compress(elen, e, h) /* e and h may be the same. */ -int elen; -REAL *e; -REAL *h; -{ - REAL Q, q; - INEXACT REAL Qnew; - int eindex, hindex; - INEXACT REAL bvirt; - REAL enow, hnow; - int top, bottom; - - bottom = elen - 1; - Q = e[bottom]; - for (eindex = elen - 2; eindex >= 0; eindex--) { - enow = e[eindex]; - Fast_Two_Sum(Q, enow, Qnew, q); - if (q != 0) { - h[bottom--] = Qnew; - Q = q; - } else { - Q = Qnew; - } - } - top = 0; - for (hindex = bottom + 1; hindex < elen; hindex++) { - hnow = h[hindex]; - Fast_Two_Sum(hnow, Q, Qnew, q); - if (q != 0) { - h[top++] = q; - } - Q = Qnew; - } - h[top] = Q; - return top + 1; -} - -/*****************************************************************************/ -/* */ -/* estimate() Produce a one-word estimate of an expansion's value. */ -/* */ -/* See either version of my paper for details. */ -/* */ -/*****************************************************************************/ - -REAL estimate(elen, e) -int elen; -REAL *e; -{ - REAL Q; - int eindex; - - Q = e[0]; - for (eindex = 1; eindex < elen; eindex++) { - Q += e[eindex]; - } - return Q; -} - -/*****************************************************************************/ -/* */ -/* orient2dfast() Approximate 2D orientation test. Nonrobust. */ -/* orient2dexact() Exact 2D orientation test. Robust. */ -/* orient2dslow() Another exact 2D orientation test. Robust. */ -/* orient2d() Adaptive exact 2D orientation test. Robust. */ -/* */ -/* Return a positive value if the points pa, pb, and pc occur */ -/* in counterclockwise order; a negative value if they occur */ -/* in clockwise order; and zero if they are collinear. The */ -/* result is also a rough approximation of twice the signed */ -/* area of the triangle defined by the three points. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient2d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient2d() is usually quite */ -/* fast, but will run more slowly when the input points are collinear or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient2dfast(pa, pb, pc) -REAL *pa; -REAL *pb; -REAL *pc; -{ - REAL acx, bcx, acy, bcy; - - acx = pa[0] - pc[0]; - bcx = pb[0] - pc[0]; - acy = pa[1] - pc[1]; - bcy = pb[1] - pc[1]; - return acx * bcy - acy * bcx; -} - -REAL orient2dexact(pa, pb, pc) -REAL *pa; -REAL *pb; -REAL *pc; -{ - INEXACT REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; - REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; - REAL aterms[4], bterms[4], cterms[4]; - INEXACT REAL aterms3, bterms3, cterms3; - REAL v[8], w[12]; - int vlength, wlength; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Two_Diff(axby1, axby0, axcy1, axcy0, - aterms3, aterms[2], aterms[1], aterms[0]); - aterms[3] = aterms3; - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, - bterms3, bterms[2], bterms[1], bterms[0]); - bterms[3] = bterms3; - - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, - cterms3, cterms[2], cterms[1], cterms[0]); - cterms[3] = cterms3; - - vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); - wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); - - return w[wlength - 1]; -} - -REAL orient2dslow(pa, pb, pc) -REAL *pa; -REAL *pb; -REAL *pc; -{ - INEXACT REAL acx, acy, bcx, bcy; - REAL acxtail, acytail; - REAL bcxtail, bcytail; - REAL negate, negatetail; - REAL axby[8], bxay[8]; - INEXACT REAL axby7, bxay7; - REAL deter[16]; - int deterlen; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pc[0], acx, acxtail); - Two_Diff(pa[1], pc[1], acy, acytail); - Two_Diff(pb[0], pc[0], bcx, bcxtail); - Two_Diff(pb[1], pc[1], bcy, bcytail); - - Two_Two_Product(acx, acxtail, bcy, bcytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -acy; - negatetail = -acytail; - Two_Two_Product(bcx, bcxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - - deterlen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, deter); - - return deter[deterlen - 1]; -} - -REAL orient2dadapt(pa, pb, pc, detsum) -REAL *pa; -REAL *pb; -REAL *pc; -REAL detsum; -{ - INEXACT REAL acx, acy, bcx, bcy; - REAL acxtail, acytail, bcxtail, bcytail; - INEXACT REAL detleft, detright; - REAL detlefttail, detrighttail; - REAL det, errbound; - REAL B[4], C1[8], C2[12], D[16]; - INEXACT REAL B3; - int C1length, C2length, Dlength; - REAL u[4]; - INEXACT REAL u3; - INEXACT REAL s1, t1; - REAL s0, t0; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - acx = (REAL) (pa[0] - pc[0]); - bcx = (REAL) (pb[0] - pc[0]); - acy = (REAL) (pa[1] - pc[1]); - bcy = (REAL) (pb[1] - pc[1]); - - Two_Product(acx, bcy, detleft, detlefttail); - Two_Product(acy, bcx, detright, detrighttail); - - Two_Two_Diff(detleft, detlefttail, detright, detrighttail, - B3, B[2], B[1], B[0]); - B[3] = B3; - - det = estimate(4, B); - errbound = ccwerrboundB * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pc[0], acx, acxtail); - Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); - Two_Diff_Tail(pa[1], pc[1], acy, acytail); - Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); - - if ((acxtail == 0.0) && (acytail == 0.0) - && (bcxtail == 0.0) && (bcytail == 0.0)) { - return det; - } - - errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); - det += (acx * bcytail + bcy * acxtail) - - (acy * bcxtail + bcx * acytail); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Product(acxtail, bcy, s1, s0); - Two_Product(acytail, bcx, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); - - Two_Product(acx, bcytail, s1, s0); - Two_Product(acy, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); - - Two_Product(acxtail, bcytail, s1, s0); - Two_Product(acytail, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); - - return(D[Dlength - 1]); -} - -REAL orient2d(pa, pb, pc) -REAL *pa; -REAL *pb; -REAL *pc; -{ - REAL detleft, detright, det; - REAL detsum, errbound; - - detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); - detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); - det = detleft - detright; - - if (detleft > 0.0) { - if (detright <= 0.0) { - return det; - } else { - detsum = detleft + detright; - } - } else if (detleft < 0.0) { - if (detright >= 0.0) { - return det; - } else { - detsum = -detleft - detright; - } - } else { - return det; - } - - errbound = ccwerrboundA * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return orient2dadapt(pa, pb, pc, detsum); -} - -/*****************************************************************************/ -/* */ -/* orient3dfast() Approximate 3D orientation test. Nonrobust. */ -/* orient3dexact() Exact 3D orientation test. Robust. */ -/* orient3dslow() Another exact 3D orientation test. Robust. */ -/* orient3d() Adaptive exact 3D orientation test. Robust. */ -/* */ -/* Return a positive value if the point pd lies below the */ -/* plane passing through pa, pb, and pc; "below" is defined so */ -/* that pa, pb, and pc appear in counterclockwise order when */ -/* viewed from above the plane. Returns a negative value if */ -/* pd lies above the plane. Returns zero if the points are */ -/* coplanar. The result is also a rough approximation of six */ -/* times the signed volume of the tetrahedron defined by the */ -/* four points. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient3d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient3d() is usually quite */ -/* fast, but will run more slowly when the input points are coplanar or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient3dfast(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - REAL adx, bdx, cdx; - REAL ady, bdy, cdy; - REAL adz, bdz, cdz; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adz = pa[2] - pd[2]; - bdz = pb[2] - pd[2]; - cdz = pc[2] - pd[2]; - - return adx * (bdy * cdz - bdz * cdy) - + bdx * (cdy * adz - cdz * ady) - + cdx * (ady * bdz - adz * bdy); -} - -REAL orient3dexact(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen, bcdlen, cdalen, dablen; - REAL adet[24], bdet[24], cdet[24], ddet[24]; - int alen, blen, clen, dlen; - REAL abdet[48], cddet[48]; - int ablen, cdlen; - REAL deter[96]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); - blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); - clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); - dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL orient3dslow(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - INEXACT REAL adx, ady, adz, bdx, bdy, bdz, cdx, cdy, cdz; - REAL adxtail, adytail, adztail; - REAL bdxtail, bdytail, bdztail; - REAL cdxtail, cdytail, cdztail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; - REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; - REAL temp16[16], temp32[32], temp32t[32]; - int temp16len, temp32len, temp32tlen; - REAL adet[64], bdet[64], cdet[64]; - int alen, blen, clen; - REAL abdet[128]; - int ablen; - REAL deter[192]; - int deterlen; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pd[0], adx, adxtail); - Two_Diff(pa[1], pd[1], ady, adytail); - Two_Diff(pa[2], pd[2], adz, adztail); - Two_Diff(pb[0], pd[0], bdx, bdxtail); - Two_Diff(pb[1], pd[1], bdy, bdytail); - Two_Diff(pb[2], pd[2], bdz, bdztail); - Two_Diff(pc[0], pd[0], cdx, cdxtail); - Two_Diff(pc[1], pd[1], cdy, cdytail); - Two_Diff(pc[2], pd[2], cdz, cdztail); - - Two_Two_Product(adx, adxtail, bdy, bdytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -ady; - negatetail = -adytail; - Two_Two_Product(bdx, bdxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - Two_Two_Product(bdx, bdxtail, cdy, cdytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bdy; - negatetail = -bdytail; - Two_Two_Product(cdx, cdxtail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - Two_Two_Product(cdx, cdxtail, ady, adytail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - negate = -cdy; - negatetail = -cdytail; - Two_Two_Product(adx, adxtail, negate, negatetail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - - temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, adz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, adztail, temp32t); - alen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - adet); - - temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, bdz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, bdztail, temp32t); - blen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - bdet); - - temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, cdz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, cdztail, temp32t); - clen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); - - return deter[deterlen - 1]; -} - -REAL orient3dadapt(pa, pb, pc, pd, permanent) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL permanent; -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL adet[8], bdet[8], cdet[8]; - int alen, blen, clen; - REAL abdet[16]; - int ablen; - REAL *finnow, *finother, *finswap; - REAL fin1[192], fin2[192]; - int finlength; - - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL adztail, bdztail, cdztail; - INEXACT REAL at_blarge, at_clarge; - INEXACT REAL bt_clarge, bt_alarge; - INEXACT REAL ct_alarge, ct_blarge; - REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; - int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; - INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; - INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; - REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; - REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; - INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; - INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; - REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; - REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; - REAL bct[8], cat[8], abt[8]; - int bctlen, catlen, abtlen; - INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; - INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; - REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; - REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; - REAL u[4], v[12], w[16]; - INEXACT REAL u3; - int vlength, wlength; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - adz = (REAL) (pa[2] - pd[2]); - bdz = (REAL) (pb[2] - pd[2]); - cdz = (REAL) (pc[2] - pd[2]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - alen = scale_expansion_zeroelim(4, bc, adz, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - blen = scale_expansion_zeroelim(4, ca, bdz, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - clen = scale_expansion_zeroelim(4, ab, cdz, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = o3derrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - Two_Diff_Tail(pa[2], pd[2], adz, adztail); - Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); - Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); - - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) - && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { - return det; - } - - errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); - det += (adz * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + adztail * (bdx * cdy - bdy * cdx)) - + (bdz * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + bdztail * (cdx * ady - cdy * adx)) - + (cdz * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + cdztail * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if (adxtail == 0.0) { - if (adytail == 0.0) { - at_b[0] = 0.0; - at_blen = 1; - at_c[0] = 0.0; - at_clen = 1; - } else { - negate = -adytail; - Two_Product(negate, bdx, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - Two_Product(adytail, cdx, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } - } else { - if (adytail == 0.0) { - Two_Product(adxtail, bdy, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - negate = -adxtail; - Two_Product(negate, cdy, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } else { - Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); - Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); - Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, - at_blarge, at_b[2], at_b[1], at_b[0]); - at_b[3] = at_blarge; - at_blen = 4; - Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); - Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); - Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, - at_clarge, at_c[2], at_c[1], at_c[0]); - at_c[3] = at_clarge; - at_clen = 4; - } - } - if (bdxtail == 0.0) { - if (bdytail == 0.0) { - bt_c[0] = 0.0; - bt_clen = 1; - bt_a[0] = 0.0; - bt_alen = 1; - } else { - negate = -bdytail; - Two_Product(negate, cdx, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - Two_Product(bdytail, adx, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } - } else { - if (bdytail == 0.0) { - Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - negate = -bdxtail; - Two_Product(negate, ady, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } else { - Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); - Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); - Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, - bt_clarge, bt_c[2], bt_c[1], bt_c[0]); - bt_c[3] = bt_clarge; - bt_clen = 4; - Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); - Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); - Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, - bt_alarge, bt_a[2], bt_a[1], bt_a[0]); - bt_a[3] = bt_alarge; - bt_alen = 4; - } - } - if (cdxtail == 0.0) { - if (cdytail == 0.0) { - ct_a[0] = 0.0; - ct_alen = 1; - ct_b[0] = 0.0; - ct_blen = 1; - } else { - negate = -cdytail; - Two_Product(negate, adx, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } - } else { - if (cdytail == 0.0) { - Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - negate = -cdxtail; - Two_Product(negate, bdy, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } else { - Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); - Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); - Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, - ct_alarge, ct_a[2], ct_a[1], ct_a[0]); - ct_a[3] = ct_alarge; - ct_alen = 4; - Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); - Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); - Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, - ct_blarge, ct_b[2], ct_b[1], ct_b[0]); - ct_b[3] = ct_blarge; - ct_blen = 4; - } - } - - bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); - wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); - wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); - wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - if (adztail != 0.0) { - vlength = scale_expansion_zeroelim(4, bc, adztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ca, bdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ab, cdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if (adxtail != 0.0) { - if (bdytail != 0.0) { - Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (cdytail != 0.0) { - negate = -adxtail; - Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (bdxtail != 0.0) { - if (cdytail != 0.0) { - Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (adytail != 0.0) { - negate = -bdxtail; - Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (cdxtail != 0.0) { - if (adytail != 0.0) { - Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (bdytail != 0.0) { - negate = -cdxtail; - Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - - if (adztail != 0.0) { - wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - return finnow[finlength - 1]; -} - -REAL orient3d(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adz = pa[2] - pd[2]; - bdz = pb[2] - pd[2]; - cdz = pc[2] - pd[2]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - - det = adz * (bdxcdy - cdxbdy) - + bdz * (cdxady - adxcdy) - + cdz * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) - + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) - + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); - errbound = o3derrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return orient3dadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* incirclefast() Approximate 2D incircle test. Nonrobust. */ -/* incircleexact() Exact 2D incircle test. Robust. */ -/* incircleslow() Another exact 2D incircle test. Robust. */ -/* incircle() Adaptive exact 2D incircle test. Robust. */ -/* */ -/* Return a positive value if the point pd lies inside the */ -/* circle passing through pa, pb, and pc; a negative value if */ -/* it lies outside; and zero if the four points are cocircular.*/ -/* The points pa, pb, and pc must be in counterclockwise */ -/* order, or the sign of the result will be reversed. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In incircle() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, incircle() is usually quite */ -/* fast, but will run more slowly when the input points are cocircular or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL incirclefast(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - REAL adx, ady, bdx, bdy, cdx, cdy; - REAL abdet, bcdet, cadet; - REAL alift, blift, clift; - - adx = pa[0] - pd[0]; - ady = pa[1] - pd[1]; - bdx = pb[0] - pd[0]; - bdy = pb[1] - pd[1]; - cdx = pc[0] - pd[0]; - cdy = pc[1] - pd[1]; - - abdet = adx * bdy - bdx * ady; - bcdet = bdx * cdy - cdx * bdy; - cadet = cdx * ady - adx * cdy; - alift = adx * adx + ady * ady; - blift = bdx * bdx + bdy * bdy; - clift = cdx * cdx + cdy * cdy; - - return alift * bcdet + blift * cadet + clift * abdet; -} - -REAL incircleexact(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen, bcdlen, cdalen, dablen; - REAL det24x[24], det24y[24], det48x[48], det48y[48]; - int xlen, ylen; - REAL adet[96], bdet[96], cdet[96], ddet[96]; - int alen, blen, clen, dlen; - REAL abdet[192], cddet[192]; - int ablen, cdlen; - REAL deter[384]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); - ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); - alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); - - xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); - ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); - blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); - - xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); - ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); - clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); - - xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); - ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); - dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL incircleslow(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; - REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; - REAL temp16[16]; - int temp16len; - REAL detx[32], detxx[64], detxt[32], detxxt[64], detxtxt[64]; - int xlen, xxlen, xtlen, xxtlen, xtxtlen; - REAL x1[128], x2[192]; - int x1len, x2len; - REAL dety[32], detyy[64], detyt[32], detyyt[64], detytyt[64]; - int ylen, yylen, ytlen, yytlen, ytytlen; - REAL y1[128], y2[192]; - int y1len, y2len; - REAL adet[384], bdet[384], cdet[384], abdet[768], deter[1152]; - int alen, blen, clen, ablen, deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pd[0], adx, adxtail); - Two_Diff(pa[1], pd[1], ady, adytail); - Two_Diff(pb[0], pd[0], bdx, bdxtail); - Two_Diff(pb[1], pd[1], bdy, bdytail); - Two_Diff(pc[0], pd[0], cdx, cdxtail); - Two_Diff(pc[1], pd[1], cdy, cdytail); - - Two_Two_Product(adx, adxtail, bdy, bdytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -ady; - negatetail = -adytail; - Two_Two_Product(bdx, bdxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - Two_Two_Product(bdx, bdxtail, cdy, cdytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bdy; - negatetail = -bdytail; - Two_Two_Product(cdx, cdxtail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - Two_Two_Product(cdx, cdxtail, ady, adytail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - negate = -cdy; - negatetail = -cdytail; - Two_Two_Product(adx, adxtail, negate, negatetail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - - - temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, adx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, adx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, adxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, adx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, adxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, ady, dety); - yylen = scale_expansion_zeroelim(ylen, dety, ady, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, adytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, ady, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, adytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - alen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, adet); - - - temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, bdx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, bdx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, bdxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, bdx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bdxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, bdy, dety); - yylen = scale_expansion_zeroelim(ylen, dety, bdy, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, bdytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, bdy, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, bdytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - blen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, bdet); - - - temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, cdx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, cdx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, cdxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, cdx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cdxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, cdy, dety); - yylen = scale_expansion_zeroelim(ylen, dety, cdy, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, cdytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, cdy, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, cdytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - clen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); - - return deter[deterlen - 1]; -} - -REAL incircleadapt(pa, pb, pc, pd, permanent) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL permanent; -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; - int axbclen, axxbclen, aybclen, ayybclen, alen; - REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; - int bxcalen, bxxcalen, bycalen, byycalen, blen; - REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; - int cxablen, cxxablen, cyablen, cyyablen, clen; - REAL abdet[64]; - int ablen; - REAL fin1[1152], fin2[1152]; - REAL *finnow, *finother, *finswap; - int finlength; - - REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; - INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; - REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; - REAL aa[4], bb[4], cc[4]; - INEXACT REAL aa3, bb3, cc3; - INEXACT REAL ti1, tj1; - REAL ti0, tj0; - REAL u[4], v[4]; - INEXACT REAL u3, v3; - REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; - REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; - int temp8len, temp16alen, temp16blen, temp16clen; - int temp32alen, temp32blen, temp48len, temp64len; - REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; - int axtbblen, axtcclen, aytbblen, aytcclen; - REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; - int bxtaalen, bxtcclen, bytaalen, bytcclen; - REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; - int cxtaalen, cxtbblen, cytaalen, cytbblen; - REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; - int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen; - REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; - int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; - REAL axtbctt[8], aytbctt[8], bxtcatt[8]; - REAL bytcatt[8], cxtabtt[8], cytabtt[8]; - int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; - REAL abt[8], bct[8], cat[8]; - int abtlen, bctlen, catlen; - REAL abtt[4], bctt[4], catt[4]; - int abttlen, bcttlen, cattlen; - INEXACT REAL abtt3, bctt3, catt3; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); - axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); - aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); - ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); - alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); - bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); - bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); - byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); - blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); - cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); - cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); - cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); - clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = iccerrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { - return det; - } - - errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); - det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) - + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) - + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Square(adx, adxadx1, adxadx0); - Square(ady, adyady1, adyady0); - Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); - aa[3] = aa3; - } - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Square(bdx, bdxbdx1, bdxbdx0); - Square(bdy, bdybdy1, bdybdy0); - Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); - bb[3] = bb3; - } - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Square(cdx, cdxcdx1, cdxcdx0); - Square(cdy, cdycdy1, cdycdy0); - Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); - cc[3] = cc3; - } - - if (adxtail != 0.0) { - axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, - temp16a); - - axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); - temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); - - axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); - temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, - temp16a); - - aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); - temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); - - aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); - temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdxtail != 0.0) { - bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, - temp16a); - - bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); - temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); - - bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); - temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, - temp16a); - - bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); - temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); - - bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); - temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdxtail != 0.0) { - cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, - temp16a); - - cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); - temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); - - cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); - temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); - temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, - temp16a); - - cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); - temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); - - cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); - temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if ((adxtail != 0.0) || (adytail != 0.0)) { - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Two_Product(bdxtail, cdy, ti1, ti0); - Two_Product(bdx, cdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -bdy; - Two_Product(cdxtail, negate, ti1, ti0); - negate = -bdytail; - Two_Product(cdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); - - Two_Product(bdxtail, cdytail, ti1, ti0); - Two_Product(cdxtail, bdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); - bctt[3] = bctt3; - bcttlen = 4; - } else { - bct[0] = 0.0; - bctlen = 1; - bctt[0] = 0.0; - bcttlen = 1; - } - - if (adxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); - axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, - temp32a); - axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); - temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, - temp16a); - temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); - aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, - temp32a); - aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); - temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, - temp16a); - temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((bdxtail != 0.0) || (bdytail != 0.0)) { - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Two_Product(cdxtail, ady, ti1, ti0); - Two_Product(cdx, adytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -cdy; - Two_Product(adxtail, negate, ti1, ti0); - negate = -cdytail; - Two_Product(adx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); - - Two_Product(cdxtail, adytail, ti1, ti0); - Two_Product(adxtail, cdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); - catt[3] = catt3; - cattlen = 4; - } else { - cat[0] = 0.0; - catlen = 1; - catt[0] = 0.0; - cattlen = 1; - } - - if (bdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); - bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, - temp32a); - bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); - temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, - temp16a); - temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); - bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, - temp32a); - bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); - temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, - temp16a); - temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((cdxtail != 0.0) || (cdytail != 0.0)) { - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Two_Product(adxtail, bdy, ti1, ti0); - Two_Product(adx, bdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -ady; - Two_Product(bdxtail, negate, ti1, ti0); - negate = -adytail; - Two_Product(bdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); - - Two_Product(adxtail, bdytail, ti1, ti0); - Two_Product(bdxtail, adytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); - abtt[3] = abtt3; - abttlen = 4; - } else { - abt[0] = 0.0; - abtlen = 1; - abtt[0] = 0.0; - abttlen = 1; - } - - if (cdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); - cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, - temp32a); - cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); - temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, - temp16a); - temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); - cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, - temp32a); - cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); - temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, - temp16a); - temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - - return finnow[finlength - 1]; -} - -REAL incircle(pa, pb, pc, pd) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -{ - REAL adx, bdx, cdx, ady, bdy, cdy; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL alift, blift, clift; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - alift = adx * adx + ady * ady; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - blift = bdx * bdx + bdy * bdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - clift = cdx * cdx + cdy * cdy; - - det = alift * (bdxcdy - cdxbdy) - + blift * (cdxady - adxcdy) - + clift * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift - + (Absolute(cdxady) + Absolute(adxcdy)) * blift - + (Absolute(adxbdy) + Absolute(bdxady)) * clift; - errbound = iccerrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return incircleadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* inspherefast() Approximate 3D insphere test. Nonrobust. */ -/* insphereexact() Exact 3D insphere test. Robust. */ -/* insphereslow() Another exact 3D insphere test. Robust. */ -/* insphere() Adaptive exact 3D insphere test. Robust. */ -/* */ -/* Return a positive value if the point pe lies inside the */ -/* sphere passing through pa, pb, pc, and pd; a negative value */ -/* if it lies outside; and zero if the five points are */ -/* cospherical. The points pa, pb, pc, and pd must be ordered */ -/* so that they have a positive orientation (as defined by */ -/* orient3d()), or the sign of the result will be reversed. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In insphere() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, insphere() is usually quite */ -/* fast, but will run more slowly when the input points are cospherical or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL inspherefast(pa, pb, pc, pd, pe) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL *pe; -{ - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL alift, blift, clift, dlift; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - - ab = aex * bey - bex * aey; - bc = bex * cey - cex * bey; - cd = cex * dey - dex * cey; - da = dex * aey - aex * dey; - - ac = aex * cey - cex * aey; - bd = bex * dey - dex * bey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - alift = aex * aex + aey * aey + aez * aez; - blift = bex * bex + bey * bey + bez * bez; - clift = cex * cex + cey * cey + cez * cez; - dlift = dex * dex + dey * dey + dez * dez; - - return (dlift * abc - clift * dab) + (blift * cda - alift * bcd); -} - -REAL insphereexact(pa, pb, pc, pd, pe) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL *pe; -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; - INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; - INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; - INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; - REAL axby0, bxcy0, cxdy0, dxey0, exay0; - REAL bxay0, cxby0, dxcy0, exdy0, axey0; - REAL axcy0, bxdy0, cxey0, dxay0, exby0; - REAL cxay0, dxby0, excy0, axdy0, bxey0; - REAL ab[4], bc[4], cd[4], de[4], ea[4]; - REAL ac[4], bd[4], ce[4], da[4], eb[4]; - REAL temp8a[8], temp8b[8], temp16[16]; - int temp8alen, temp8blen, temp16len; - REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; - REAL abd[24], bce[24], cda[24], deb[24], eac[24]; - int abclen, bcdlen, cdelen, dealen, eablen; - int abdlen, bcelen, cdalen, deblen, eaclen; - REAL temp48a[48], temp48b[48]; - int temp48alen, temp48blen; - REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; - int abcdlen, bcdelen, cdealen, deablen, eabclen; - REAL temp192[192]; - REAL det384x[384], det384y[384], det384z[384]; - int xlen, ylen, zlen; - REAL detxy[768]; - int xylen; - REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; - int alen, blen, clen, dlen, elen; - REAL abdet[2304], cddet[2304], cdedet[3456]; - int ablen, cdlen; - REAL deter[5760]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pe[1], dxey1, dxey0); - Two_Product(pe[0], pd[1], exdy1, exdy0); - Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); - - Two_Product(pe[0], pa[1], exay1, exay0); - Two_Product(pa[0], pe[1], axey1, axey0); - Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - Two_Product(pc[0], pe[1], cxey1, cxey0); - Two_Product(pe[0], pc[1], excy1, excy0); - Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pe[0], pb[1], exby1, exby0); - Two_Product(pb[0], pe[1], bxey1, bxey0); - Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); - - temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); - abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abc); - - temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); - bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bcd); - - temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); - cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cde); - - temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); - dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - dea); - - temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); - eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eab); - - temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); - abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abd); - - temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); - bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bce); - - temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); - cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cda); - - temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); - deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - deb); - - temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); - eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eac); - - temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); - temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, bcde); - xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); - ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); - zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); - - temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); - temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, cdea); - xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); - ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); - zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); - - temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); - temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, deab); - xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); - ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); - zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); - - temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); - temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, eabc); - xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); - ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); - zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); - - temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); - temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, abcd); - xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); - ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); - zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); - - return deter[deterlen - 1]; -} - -REAL insphereslow(pa, pb, pc, pd, pe) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL *pe; -{ - INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, cxdy7, dxay7, axcy7, bxdy7; - INEXACT REAL bxay7, cxby7, dxcy7, axdy7, cxay7, dxby7; - REAL axby[8], bxcy[8], cxdy[8], dxay[8], axcy[8], bxdy[8]; - REAL bxay[8], cxby[8], dxcy[8], axdy[8], cxay[8], dxby[8]; - REAL ab[16], bc[16], cd[16], da[16], ac[16], bd[16]; - int ablen, bclen, cdlen, dalen, aclen, bdlen; - REAL temp32a[32], temp32b[32], temp64a[64], temp64b[64], temp64c[64]; - int temp32alen, temp32blen, temp64alen, temp64blen, temp64clen; - REAL temp128[128], temp192[192]; - int temp128len, temp192len; - REAL detx[384], detxx[768], detxt[384], detxxt[768], detxtxt[768]; - int xlen, xxlen, xtlen, xxtlen, xtxtlen; - REAL x1[1536], x2[2304]; - int x1len, x2len; - REAL dety[384], detyy[768], detyt[384], detyyt[768], detytyt[768]; - int ylen, yylen, ytlen, yytlen, ytytlen; - REAL y1[1536], y2[2304]; - int y1len, y2len; - REAL detz[384], detzz[768], detzt[384], detzzt[768], detztzt[768]; - int zlen, zzlen, ztlen, zztlen, ztztlen; - REAL z1[1536], z2[2304]; - int z1len, z2len; - REAL detxy[4608]; - int xylen; - REAL adet[6912], bdet[6912], cdet[6912], ddet[6912]; - int alen, blen, clen, dlen; - REAL abdet[13824], cddet[13824], deter[27648]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pe[0], aex, aextail); - Two_Diff(pa[1], pe[1], aey, aeytail); - Two_Diff(pa[2], pe[2], aez, aeztail); - Two_Diff(pb[0], pe[0], bex, bextail); - Two_Diff(pb[1], pe[1], bey, beytail); - Two_Diff(pb[2], pe[2], bez, beztail); - Two_Diff(pc[0], pe[0], cex, cextail); - Two_Diff(pc[1], pe[1], cey, ceytail); - Two_Diff(pc[2], pe[2], cez, ceztail); - Two_Diff(pd[0], pe[0], dex, dextail); - Two_Diff(pd[1], pe[1], dey, deytail); - Two_Diff(pd[2], pe[2], dez, deztail); - - Two_Two_Product(aex, aextail, bey, beytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -aey; - negatetail = -aeytail; - Two_Two_Product(bex, bextail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - ablen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, ab); - Two_Two_Product(bex, bextail, cey, ceytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bey; - negatetail = -beytail; - Two_Two_Product(cex, cextail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - bclen = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, bc); - Two_Two_Product(cex, cextail, dey, deytail, - cxdy7, cxdy[6], cxdy[5], cxdy[4], - cxdy[3], cxdy[2], cxdy[1], cxdy[0]); - cxdy[7] = cxdy7; - negate = -cey; - negatetail = -ceytail; - Two_Two_Product(dex, dextail, negate, negatetail, - dxcy7, dxcy[6], dxcy[5], dxcy[4], - dxcy[3], dxcy[2], dxcy[1], dxcy[0]); - dxcy[7] = dxcy7; - cdlen = fast_expansion_sum_zeroelim(8, cxdy, 8, dxcy, cd); - Two_Two_Product(dex, dextail, aey, aeytail, - dxay7, dxay[6], dxay[5], dxay[4], - dxay[3], dxay[2], dxay[1], dxay[0]); - dxay[7] = dxay7; - negate = -dey; - negatetail = -deytail; - Two_Two_Product(aex, aextail, negate, negatetail, - axdy7, axdy[6], axdy[5], axdy[4], - axdy[3], axdy[2], axdy[1], axdy[0]); - axdy[7] = axdy7; - dalen = fast_expansion_sum_zeroelim(8, dxay, 8, axdy, da); - Two_Two_Product(aex, aextail, cey, ceytail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - negate = -aey; - negatetail = -aeytail; - Two_Two_Product(cex, cextail, negate, negatetail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - aclen = fast_expansion_sum_zeroelim(8, axcy, 8, cxay, ac); - Two_Two_Product(bex, bextail, dey, deytail, - bxdy7, bxdy[6], bxdy[5], bxdy[4], - bxdy[3], bxdy[2], bxdy[1], bxdy[0]); - bxdy[7] = bxdy7; - negate = -bey; - negatetail = -beytail; - Two_Two_Product(dex, dextail, negate, negatetail, - dxby7, dxby[6], dxby[5], dxby[4], - dxby[3], dxby[2], dxby[1], dxby[0]); - dxby[7] = dxby7; - bdlen = fast_expansion_sum_zeroelim(8, bxdy, 8, dxby, bd); - - temp32alen = scale_expansion_zeroelim(cdlen, cd, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(cdlen, cd, -beztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(bdlen, bd, cez, temp32a); - temp32blen = scale_expansion_zeroelim(bdlen, bd, ceztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(bclen, bc, -dez, temp32a); - temp32blen = scale_expansion_zeroelim(bclen, bc, -deztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, aex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, aex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, aextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, aex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, aextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, aey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, aey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, aeytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, aey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, aeytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, aez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, aez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, aeztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, aez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, aeztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - alen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, adet); - - temp32alen = scale_expansion_zeroelim(dalen, da, cez, temp32a); - temp32blen = scale_expansion_zeroelim(dalen, da, ceztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(aclen, ac, dez, temp32a); - temp32blen = scale_expansion_zeroelim(aclen, ac, deztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(cdlen, cd, aez, temp32a); - temp32blen = scale_expansion_zeroelim(cdlen, cd, aeztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, bex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, bex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, bextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, bex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, bey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, bey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, beytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, bey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, beytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, bez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, bez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, beztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, bez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, beztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - blen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, bdet); - - temp32alen = scale_expansion_zeroelim(ablen, ab, -dez, temp32a); - temp32blen = scale_expansion_zeroelim(ablen, ab, -deztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(bdlen, bd, -aez, temp32a); - temp32blen = scale_expansion_zeroelim(bdlen, bd, -aeztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(dalen, da, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(dalen, da, -beztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, cex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, cex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, cextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, cex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, cey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, cey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, ceytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, cey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, ceytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, cez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, cez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, ceztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, cez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, ceztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - clen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, cdet); - - temp32alen = scale_expansion_zeroelim(bclen, bc, aez, temp32a); - temp32blen = scale_expansion_zeroelim(bclen, bc, aeztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(aclen, ac, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(aclen, ac, -beztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(ablen, ab, cez, temp32a); - temp32blen = scale_expansion_zeroelim(ablen, ab, ceztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, dex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, dex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, dextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, dex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, dextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, dey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, dey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, deytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, dey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, deytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, dez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, dez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, deztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, dez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, deztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - dlen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL insphereadapt(pa, pb, pc, pd, pe, permanent) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL *pe; -REAL permanent; -{ - INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL det, errbound; - - INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; - INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; - INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; - REAL aexbey0, bexaey0, bexcey0, cexbey0; - REAL cexdey0, dexcey0, dexaey0, aexdey0; - REAL aexcey0, cexaey0, bexdey0, dexbey0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; - REAL abeps, bceps, cdeps, daeps, aceps, bdeps; - REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; - int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len; - REAL xdet[96], ydet[96], zdet[96], xydet[192]; - int xlen, ylen, zlen, xylen; - REAL adet[288], bdet[288], cdet[288], ddet[288]; - int alen, blen, clen, dlen; - REAL abdet[576], cddet[576]; - int ablen, cdlen; - REAL fin1[1152]; - int finlength; - - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - aex = (REAL) (pa[0] - pe[0]); - bex = (REAL) (pb[0] - pe[0]); - cex = (REAL) (pc[0] - pe[0]); - dex = (REAL) (pd[0] - pe[0]); - aey = (REAL) (pa[1] - pe[1]); - bey = (REAL) (pb[1] - pe[1]); - cey = (REAL) (pc[1] - pe[1]); - dey = (REAL) (pd[1] - pe[1]); - aez = (REAL) (pa[2] - pe[2]); - bez = (REAL) (pb[2] - pe[2]); - cez = (REAL) (pc[2] - pe[2]); - dez = (REAL) (pd[2] - pe[2]); - - Two_Product(aex, bey, aexbey1, aexbey0); - Two_Product(bex, aey, bexaey1, bexaey0); - Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - - Two_Product(bex, cey, bexcey1, bexcey0); - Two_Product(cex, bey, cexbey1, cexbey0); - Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - - Two_Product(cex, dey, cexdey1, cexdey0); - Two_Product(dex, cey, dexcey1, dexcey0); - Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); - cd[3] = cd3; - - Two_Product(dex, aey, dexaey1, dexaey0); - Two_Product(aex, dey, aexdey1, aexdey0); - Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); - da[3] = da3; - - Two_Product(aex, cey, aexcey1, aexcey0); - Two_Product(cex, aey, cexaey1, cexaey0); - Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); - ac[3] = ac3; - - Two_Product(bex, dey, bexdey1, bexdey0); - Two_Product(dex, bey, dexbey1, dexbey0); - Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); - bd[3] = bd3; - - temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); - temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); - - temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); - temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); - - temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); - temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); - - temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); - temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); - - det = estimate(finlength, fin1); - errbound = isperrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pe[0], aex, aextail); - Two_Diff_Tail(pa[1], pe[1], aey, aeytail); - Two_Diff_Tail(pa[2], pe[2], aez, aeztail); - Two_Diff_Tail(pb[0], pe[0], bex, bextail); - Two_Diff_Tail(pb[1], pe[1], bey, beytail); - Two_Diff_Tail(pb[2], pe[2], bez, beztail); - Two_Diff_Tail(pc[0], pe[0], cex, cextail); - Two_Diff_Tail(pc[1], pe[1], cey, ceytail); - Two_Diff_Tail(pc[2], pe[2], cez, ceztail); - Two_Diff_Tail(pd[0], pe[0], dex, dextail); - Two_Diff_Tail(pd[1], pe[1], dey, deytail); - Two_Diff_Tail(pd[2], pe[2], dez, deztail); - if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) - && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) - && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) - && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { - return det; - } - - errbound = isperrboundC * permanent + resulterrbound * Absolute(det); - abeps = (aex * beytail + bey * aextail) - - (aey * bextail + bex * aeytail); - bceps = (bex * ceytail + cey * bextail) - - (bey * cextail + cex * beytail); - cdeps = (cex * deytail + dey * cextail) - - (cey * dextail + dex * ceytail); - daeps = (dex * aeytail + aey * dextail) - - (dey * aextail + aex * deytail); - aceps = (aex * ceytail + cey * aextail) - - (aey * cextail + cex * aeytail); - bdeps = (bex * deytail + dey * bextail) - - (bey * dextail + dex * beytail); - det += (((bex * bex + bey * bey + bez * bez) - * ((cez * daeps + dez * aceps + aez * cdeps) - + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) - + (dex * dex + dey * dey + dez * dez) - * ((aez * bceps - bez * aceps + cez * abeps) - + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) - - ((aex * aex + aey * aey + aez * aez) - * ((bez * cdeps - cez * bdeps + dez * bceps) - + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) - + (cex * cex + cey * cey + cez * cez) - * ((dez * abeps + aez * bdeps + bez * daeps) - + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) - + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) - * (cez * da3 + dez * ac3 + aez * cd3) - + (dex * dextail + dey * deytail + dez * deztail) - * (aez * bc3 - bez * ac3 + cez * ab3)) - - ((aex * aextail + aey * aeytail + aez * aeztail) - * (bez * cd3 - cez * bd3 + dez * bc3) - + (cex * cextail + cey * ceytail + cez * ceztail) - * (dez * ab3 + aez * bd3 + bez * da3))); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return insphereexact(pa, pb, pc, pd, pe); -} - -REAL insphere(pa, pb, pc, pd, pe) -REAL *pa; -REAL *pb; -REAL *pc; -REAL *pd; -REAL *pe; -{ - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; - REAL aexcey, cexaey, bexdey, dexbey; - REAL alift, blift, clift, dlift; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - REAL aezplus, bezplus, cezplus, dezplus; - REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; - REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; - REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; - REAL det; - REAL permanent, errbound; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - - aexbey = aex * bey; - bexaey = bex * aey; - ab = aexbey - bexaey; - bexcey = bex * cey; - cexbey = cex * bey; - bc = bexcey - cexbey; - cexdey = cex * dey; - dexcey = dex * cey; - cd = cexdey - dexcey; - dexaey = dex * aey; - aexdey = aex * dey; - da = dexaey - aexdey; - - aexcey = aex * cey; - cexaey = cex * aey; - ac = aexcey - cexaey; - bexdey = bex * dey; - dexbey = dex * bey; - bd = bexdey - dexbey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - alift = aex * aex + aey * aey + aez * aez; - blift = bex * bex + bey * bey + bez * bez; - clift = cex * cex + cey * cey + cez * cez; - dlift = dex * dex + dey * dey + dez * dez; - - det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); - - aezplus = Absolute(aez); - bezplus = Absolute(bez); - cezplus = Absolute(cez); - dezplus = Absolute(dez); - aexbeyplus = Absolute(aexbey); - bexaeyplus = Absolute(bexaey); - bexceyplus = Absolute(bexcey); - cexbeyplus = Absolute(cexbey); - cexdeyplus = Absolute(cexdey); - dexceyplus = Absolute(dexcey); - dexaeyplus = Absolute(dexaey); - aexdeyplus = Absolute(aexdey); - aexceyplus = Absolute(aexcey); - cexaeyplus = Absolute(cexaey); - bexdeyplus = Absolute(bexdey); - dexbeyplus = Absolute(dexbey); - permanent = ((cexdeyplus + dexceyplus) * bezplus - + (dexbeyplus + bexdeyplus) * cezplus - + (bexceyplus + cexbeyplus) * dezplus) - * alift - + ((dexaeyplus + aexdeyplus) * cezplus - + (aexceyplus + cexaeyplus) * dezplus - + (cexdeyplus + dexceyplus) * aezplus) - * blift - + ((aexbeyplus + bexaeyplus) * dezplus - + (bexdeyplus + dexbeyplus) * aezplus - + (dexaeyplus + aexdeyplus) * bezplus) - * clift - + ((bexceyplus + cexbeyplus) * aezplus - + (cexaeyplus + aexceyplus) * bezplus - + (aexbeyplus + bexaeyplus) * cezplus) - * dlift; - errbound = isperrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return insphereadapt(pa, pb, pc, pd, pe, permanent); -} diff --git a/python/framework/predicates.h b/python/framework/predicates.h deleted file mode 100644 index a5334af..0000000 --- a/python/framework/predicates.h +++ /dev/null @@ -1,4 +0,0 @@ -double orient2d(pa, pb, pc); -double *pa; -double *pb; -double *pc; diff --git a/python/framework/seidel.pxi b/python/framework/seidel.pxi deleted file mode 100644 index a47d852..0000000 --- a/python/framework/seidel.pxi +++ /dev/null @@ -1,615 +0,0 @@ -# -# Poly2Tri -# Copyright (c) 2009, Mason Green -# http://code.google.com/p/poly2tri/ -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, -# self list of conditions and the following disclaimer. -# Redistributions in binary form must reproduce the above copyright notice, -# self list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# Neither the name of Poly2Tri nor the names of its contributors may be -# used to endorse or promote products derived from self software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -from random import shuffle - -## -## Based on Raimund Seidel'e paper "A simple and fast incremental randomized -## algorithm for computing trapezoidal decompositions and for triangulating polygons" -## (Ported from poly2tri) -## - -# Shear transform. May effect numerical robustness -SHEAR = 1e-6 - -cdef extern from 'math.h': - double atan2(double, double) - -cdef extern from 'predicates.h': - double orient2d(double *pa, double *pb, double *pc) - -class Point(object): - - def __init__(self, x, y): - self.x = x - self.y = y - self.next, self.prev = None, None - - def __sub__(self, other): - if isinstance(other, Point): - return Point(self.x - other.x, self.y - other.y) - else: - return Point(self.x - other, self.y - other) - - def __add__(self, other): - if isinstance(other, Point): - return Point(self.x + other.x, self.y + other.y) - else: - return Point(self.x + other, self.y + other) - - def __mul__(self, f): - return Point(self.x * f, self.y * f) - - def __div__(self, a): - return Point(self.x / a, self.y / a) - - def cross(self, p): - return self.x * p.y - self.y * p.x - - def dot(self, p): - return self.x * p.x + self.y * p.y - - def length(self): - return sqrt(self.x * self.x + self.y * self.y) - - def normalize(self): - return self / self.length() - - def less(self, p): - return self.x < p.x - - def neq(self, other): - return other.x != self.x or other.y != self.y - - def clone(self): - return Point(self.x, self.y) - -class Edge(object): - - def __init__(self, p, q): - self.p = p - self.q = q - self.slope = (q.y - p.y) / (q.x - p.x) - self.b = p.y - (p.x * self.slope) - self.above, self.below = None, None - self.mpoints = [] - self.mpoints.append(p) - self.mpoints.append(q) - - def is_above(self, point): - cdef double *a = [self.p.x, self.p.y] - cdef double *b = [self.q.x, self.q.y] - cdef double *c = [point.x, point.y] - return orient2d(a, b, c) < 0.0 - - def is_below(self, point): - cdef double *a = [self.p.x, self.p.y] - cdef double *b = [self.q.x, self.q.y] - cdef double *c = [point.x, point.y] - return orient2d(a, b, c) > 0.0 - -class Trapezoid(object): - - def __init__(self, left_point, right_point, top, bottom): - self.left_point = left_point - self.right_point = right_point - self.top = top - self.bottom = bottom - self.upper_left = None - self.upper_right = None - self.lower_left = None - self.lower_right = None - self.inside = True - self.sink = None - self.key = hash(self) - - def update_left(self, ul, ll): - self.upper_left = ul - if ul != None: ul.upper_right = self - self.lower_left = ll - if ll != None: ll.lower_right = self - - def update_right(self, ur, lr): - self.upper_right = ur - if ur != None: ur.upper_left = self - self.lower_right = lr - if lr != None: lr.lower_left = self - - def update_left_right(self, ul, ll, ur, lr): - self.upper_left = ul - if ul != None: ul.upper_right = self - self.lower_left = ll - if ll != None: ll.lower_right = self - self.upper_right = ur - if ur != None: ur.upper_left = self - self.lower_right = lr - if lr != None: lr.lower_left = self - - def trim_neighbors(self): - if self.inside: - self.inside = False - if self.upper_left != None: self.upper_left.trim_neighbors() - if self.lower_left != None: self.lower_left.trim_neighbors() - if self.upper_right != None: self.upper_right.trim_neighbors() - if self.lower_right != None: self.lower_right.trim_neighbors() - - def contains(self, point): - return (point.x > self.left_point.x and point.x < self.right_point.x and - self.top.is_above(point) and self.bottom.is_below(point)) - - def vertices(self): - v1 = line_intersect(self.top, self.left_point.x) - v2 = line_intersect(self.bottom, self.left_point.x) - v3 = line_intersect(self.bottom, self.right_point.x) - v4 = line_intersect(self.top, self.right_point.x) - return v1, v2, v3, v4 - - def add_points(self): - if self.left_point != self.bottom.p: - self.bottom.mpoints.append(self.left_point.clone()) - if self.right_point != self.bottom.q: - self.bottom.mpoints.append(self.right_point.clone()) - if self.left_point != self.top.p: - self.top.mpoints.append(self.left_point.clone()) - if self.right_point != self.top.q: - self.top.mpoints.append(self.right_point.clone()) - -def line_intersect(edge, x): - y = edge.slope * x + edge.b - return x, y - -class Triangulator(object): - - def __init__(self, poly_line): - self.polygons = [] - self.trapezoids = [] - self.xmono_poly = [] - self.edge_list = self.init_edges(poly_line) - self.trapezoidal_map = TrapezoidalMap() - self.bounding_box = self.trapezoidal_map.bounding_box(self.edge_list) - self.query_graph = QueryGraph(isink(self.bounding_box)) - - self.process() - - def triangles(self): - triangles = [] - for p in self.polygons: - verts = [] - for v in p: - verts.append((v.x, v.y)) - triangles.append(verts) - return triangles - - def trapezoid_map(self): - return self.trapezoidal_map.map - - # Build the trapezoidal map and query graph - def process(self): - for edge in self.edge_list: - traps = self.query_graph.follow_edge(edge) - for t in traps: - # Remove old trapezods - del self.trapezoidal_map.map[t.key] - # Bisect old trapezoids and create new - cp = t.contains(edge.p) - cq = t.contains(edge.q) - if cp and cq: - tlist = self.trapezoidal_map.case1(t, edge) - self.query_graph.case1(t.sink, edge, tlist) - elif cp and not cq: - tlist = self.trapezoidal_map.case2(t, edge) - self.query_graph.case2(t.sink, edge, tlist) - elif not cp and not cq: - tlist = self.trapezoidal_map.case3(t, edge) - self.query_graph.case3(t.sink, edge, tlist) - else: - tlist = self.trapezoidal_map.case4(t, edge) - self.query_graph.case4(t.sink, edge, tlist) - # Add new trapezoids to map - for t in tlist: - self.trapezoidal_map.map[t.key] = t - self.trapezoidal_map.clear() - - # Mark outside trapezoids w/ depth-first search - for k, t in self.trapezoidal_map.map.items(): - self.mark_outside(t) - - # Collect interior trapezoids - for k, t in self.trapezoidal_map.map.items(): - if t.inside: - self.trapezoids.append(t) - t.add_points() - - # Generate the triangles - self.create_mountains() - - def mono_polies(self): - polies = [] - for x in self.xmono_poly: - polies.append(x.monoPoly) - return polies - - def create_mountains(self): - for edge in self.edge_list: - if len(edge.mpoints) > 2: - mountain = MonotoneMountain() - points = merge_sort(edge.mpoints) - for p in points: - mountain.add(p) - mountain.process() - for t in mountain.triangles: - self.polygons.append(t) - self.xmono_poly.append(mountain) - - def mark_outside(self, t): - if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom: - t.trim_neighbors() - - def init_edges(self, points): - edge_list = [] - size = len(points) - for i in range(size): - j = i + 1 if i < size-1 else 0 - p = points[i][0], points[i][1] - q = points[j][0], points[j][1] - edge_list.append((p, q)) - return self.order_edges(edge_list) - - def order_edges(self, edge_list): - edges = [] - for e in edge_list: - p = shear_transform(e[0]) - q = shear_transform(e[1]) - if p.x > q.x: - edges.append(Edge(q, p)) - else: - edges.append(Edge(p, q)) - # Randomized incremental algorithm - shuffle(edges) - return edges - -def shear_transform(point): - return Point(point[0] + SHEAR * point[1], point[1]) - -def merge_sort(l): - if len(l)>1 : - lleft = merge_sort(l[:len(l)/2]) - lright = merge_sort(l[len(l)/2:]) - p1, p2, p = 0, 0, 0 - while p1 max.x: max = Point(e.p.x + margin, max.y) - if e.p.y > max.y: max = Point(max.x, e.p.y + margin) - if e.q.x > max.x: max = Point(e.q.x + margin, max.y) - if e.q.y > max.y: max = Point(max.x, e.q.y + margin) - if e.p.x < min.x: min = Point(e.p.x - margin, min.y) - if e.p.y < min.y: min = Point(min.x, e.p.y - margin) - if e.q.x < min.x: min = Point(e.q.x - margin, min.y) - if e.q.y < min.y: min = Point(min.x, e.q.y - margin) - top = Edge(Point(min.x, max.y), Point(max.x, max.y)) - bottom = Edge(Point(min.x, min.y), Point(max.x, min.y)) - left = top.p - right = top.q - trap = Trapezoid(left, right, top, bottom) - self.map[trap.key] = trap - return trap - -class Node(object): - - def __init__(self, lchild, rchild): - self.parent_list = [] - self.lchild = lchild - self.rchild = rchild - if lchild != None: - lchild.parent_list.append(self) - if rchild != None: - rchild.parent_list.append(self) - - def replace(self, node): - for parent in node.parent_list: - if parent.lchild is node: - parent.lchild = self - else: - parent.rchild = self - self.parent_list += node.parent_list - -class Sink(Node): - - def __init__(self, trapezoid): - super(Sink, self).__init__(None, None) - self.trapezoid = trapezoid - trapezoid.sink = self - - def locate(self, edge): - return self - -def isink(trapezoid): - if trapezoid.sink is None: - return Sink(trapezoid) - return trapezoid.sink - -class XNode(Node): - - def __init__(self, point, lchild, rchild): - super(XNode, self).__init__(lchild, rchild) - self.point = point - - def locate(self, edge): - if edge.p.x >= self.point.x: - return self.rchild.locate(edge) - return self.lchild.locate(edge) - -class YNode(Node): - - def __init__(self, edge, lchild, rchild): - super(YNode, self).__init__(lchild, rchild) - self.edge = edge - - def locate(self, edge): - if self.edge.is_above(edge.p): - return self.rchild.locate(edge) - if self.edge.is_below(edge.p): - return self.lchild.locate(edge) - if self.edge.is_above(edge.q): - return self.rchild.locate(edge) - return self.lchild.locate(edge) - -class QueryGraph: - - def __init__(self, head): - self.head = head - - def locate(self, edge): - return self.head.locate(edge).trapezoid - - def follow_edge(self, edge): - trapezoids = [self.locate(edge)] - while(edge.q.x > trapezoids[-1].right_point.x): - if edge.is_above(trapezoids[-1].right_point): - trapezoids.append(trapezoids[-1].upper_right) - else: - trapezoids.append(trapezoids[-1].lower_right) - return trapezoids - - def replace(self, sink, node): - if sink.parent_list: - node.replace(sink) - else: - self.head = node - - def case1(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[1]), isink(tlist[2])) - qNode = XNode(edge.q, yNode, isink(tlist[3])) - pNode = XNode(edge.p, isink(tlist[0]), qNode) - self.replace(sink, pNode) - - def case2(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[1]), isink(tlist[2])) - pNode = XNode(edge.p, isink(tlist[0]), yNode) - self.replace(sink, pNode) - - def case3(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[0]), isink(tlist[1])) - self.replace(sink, yNode) - - def case4(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[0]), isink(tlist[1])) - qNode = XNode(edge.q, yNode, isink(tlist[2])) - self.replace(sink, qNode) - -PI_SLOP = 3.1 - -class MonotoneMountain: - - def __init__(self): - self.size = 0 - self.tail = None - self.head = None - self.positive = False - self.convex_points = [] - self.mono_poly = [] - self.triangles = [] - self.convex_polies = [] - - def add(self, point): - if self.size is 0: - self.head = point - self.size = 1 - elif self.size is 1: - if point.neq(self.head): - self.tail = point - self.tail.prev = self.head - self.head.next = self.tail - self.size = 2 - else: - if point.neq(self.tail): - self.tail.next = point - point.prev = self.tail - self.tail = point - self.size += 1 - - def remove(self, point): - next = point.next - prev = point.prev - point.prev.next = next - point.next.prev = prev - self.size -= 1 - - def process(self): - self.positive = self.angle_sign() - self.gen_mono_poly() - p = self.head.next - while p != self.tail: - a = self.angle(p) - if a >= PI_SLOP or a <= -PI_SLOP or a == 0: - self.remove(p) - elif self.is_convex(p): - self.convex_points.append(p) - p = p.next - self.triangulate() - - def triangulate(self): - while self.convex_points: - ear = self.convex_points.pop(0) - a = ear.prev - b = ear - c = ear.next - triangle = (a, b, c) - self.triangles.append(triangle) - self.remove(ear) - if self.valid(a): - self.convex_points.append(a) - if self.valid(c): - self.convex_points.append(c) - #assert self.size <= 3, "Triangulation bug, please report" - - def valid(self, p): - return p != self.head and p != self.tail and self.is_convex(p) - - def gen_mono_poly(self): - p = self.head - while(p != None): - self.mono_poly.append(p) - p = p.next - - def angle(self, p): - a = p.next - p - b = p.prev - p - return atan2(a.cross(b), a.dot(b)) - - def angle_sign(self): - a = self.head.next - self.head - b = self.tail - self.head - return atan2(a.cross(b), a.dot(b)) >= 0 - - def is_convex(self, p): - if self.positive != (self.angle(p) >= 0): - return False - return True \ No newline at end of file diff --git a/python/framework/triangulator.pyx b/python/framework/triangulator.pyx deleted file mode 100644 index a706676..0000000 --- a/python/framework/triangulator.pyx +++ /dev/null @@ -1,707 +0,0 @@ -# -# Poly2Tri -# Copyright (c) 2009, Mason Green -# http://code.google.com/p/poly2tri/ -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, -# self list of conditions and the following disclaimer. -# Redistributions in binary form must reproduce the above copyright notice, -# self list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# Neither the name of Poly2Tri nor the names of its contributors may be -# used to endorse or promote products derived from self software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -from random import shuffle - -### -### Based on Raimund Seidel'e paper "A simple and fast incremental randomized -### algorithm for computing trapezoidal decompositions and for triangulating polygons" -### (Ported from poly2tri) - -cdef extern from 'math.h': - double cos(double) - double sin(double) - double atan2(double, double) - double floor(double) - double sqrt(double) - -class Point: - - def __cinit__(self, float x, float y): - self.x = x - self.y = y - - def __sub__(self, other): - if isinstance(other, Point): - return Point(self.x - other.x, self.y - other.y) - else: - return Point(self.x - other, self.y - other) - - def __add__(self, other): - if isinstance(other, Point): - return Point(self.x + other.x, self.y + other.y) - else: - return Point(self.x + other, self.y + other) - - def __mul__(self, float f): - return Point(self.x * f, self.y * f) - - def __div__(self, float a): - return Point(self.x / a, self.y / a) - - def cross(self, p): - return self.x * p.y - self.y * p.x - - def dot(self, p): - return self.x * p.x + self.y * p.y - - def length(self): - return sqrt(self.x * self.x + self.y * self.y) - - def normalize(self): - return self / self.length() - - def less(self, p): - return self.x < p.x - - def not_equal(self, p): - return not (p.x == self.x and p.y == self.y) - - def clone(self): - return Point(self.x, self.y) - -cdef class Edge: - - cdef object above, below - cdef float slope, b - mpoints = [] - - def __cinit__(self, p, q): - self.p = p - self.q = q - self.slope = (q.y - p.y)/(q.x - p.x) - self.b = p.y - (p.x * self.slope) - - property p: - def __get__(self): return self.p - - property q: - def __get__(self): return self.q - - property above: - def __get__(self): return self.above - - property below: - def __get__(self): return self.below - - cdef bool is_above(self, point): - return (floor(point.y) < floor(self.slope * point.x + self.b)) - cdef bool is_below(self, point): - return (floor(point.y) > floor(self.slope * point.x + self.b)) - - cdef float intersect(self, c, d): - cdef float a1, a2, a3, a4, t - cdef Point a, b - a = self.p - b = self.q - a1 = self.signed_area(a, b, d) - a2 = self.signed_area(a, b, c) - if a1 != 0 and a2 != 0 and (a1 * a2) < 0: - a3 = self.signed_area(c, d, a) - a4 = a3 + a2 - a1 - if a3 * a4 < 0: - t = a3 / (a3 - a4) - return a + ((b - a) * t) - return 0.0 - - cdef float signed_area(self, a, b, c): - return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x) - -cdef class Trapezoid: - - cdef Edge top, bottom - cdef Trapezoid upper_left, lower_left - cdef Trapezoid upper_right, lower_right - cdef object sink - cdef bool inside - - def __cinit__(self, left_point, right_point, Edge top, Edge bottom): - self.left_point = left_point - self.right_point = right_point - self.top = top - self.bottom = bottom - self.upper_left = None - self.upper_right = None - self.lower_left = None - self.lower_right = None - self.inside = True - self.sink = None - - property inside: - def __get__(self): return self.inside - - property top: - def __get__(self): return self.top - - property bottom: - def __get__(self): return self.bottom - - property left_point: - def __get__(self): return self.left_point - def __set__(self, lp): self.left_point = lp - - property right_point: - def __get__(self): return self.right_point - def __set__(self, rp): self.right_point = rp - - property sink: - def __get__(self): return self.sink - def __set__(self, object s): self.sink = s - - property upper_left: - def __get__(self): return self.upper_left - def __set__(self, Trapezoid other): self.upper_left = other - - property upper_right: - def __get__(self): return self.upper_right - def __set__(self, Trapezoid other): self.upper_right = other - - property lower_left: - def __get__(self): return self.lower_left - def __set__(self, Trapezoid other): self.lower_left = other - - property lower_right: - def __get__(self): return self.lower_right - def __set__(self, Trapezoid other): self.lower_right = other - - def update_left(self, Trapezoid ul, Trapezoid ll): - self.upper_left = ul - self.lower_left = ll - if ul != None: ul.upper_right = self - if ll != None: ll.lower_right = self - - def update_right(self, Trapezoid ur, Trapezoid lr): - self.upper_right = ur - self.lower_right = lr - if ur != None: ur.upper_left = self - if lr != None: lr.lower_left = self - - def update_left_right(self, Trapezoid ul, Trapezoid ll, Trapezoid ur, Trapezoid lr): - self.upper_left = ul - self.lower_left = ll - self.upper_right = ur - self.lower_right = lr - if ul != None: ul.upper_right = self - if ll != None: ll.lower_right = self - if ur != None: ur.upper_left = self - if lr != None: lr.lower_left = self - - def trim_neighbors(self): - if self.inside: - self.inside = False - if self.upper_left != None: self.upper_left.trim_neighbors() - if self.lower_left != None: self.lower_left.trim_neighbors() - if self.upper_right != None: self.upper_right.trim_neighbors() - if self.lower_right != None: self.lower_right.trim_neighbors() - - def contains(self, point): - return (point.x > self.left_point.x and point.x < self.right_point.x and - self.top.is_above(point) and self.bottom.is_below(point)) - - def vertices(self): - cdef list verts = [] - verts.append(line_intersect(self.top, self.left_point.x)) - verts.append(line_intersect(self.bottom, self.left_point.x)) - verts.append(line_intersect(self.bottom, self.right_point.x)) - verts.append(line_intersect(self.top, self.right_point.x)) - return verts - - def add_points(self): - if self.left_point != self.bottom.p: - self.bottom.mpoints.append(self.left_point.clone) - if self.right_point != self.bottom.q: - self.bottom.mpoints.append(self.right_point.clone) - if self.left_point != self.top.p: - self.top.mpoints.append(self.left_point.clone) - if self.right_point != self.top.q: - self.top.mpoints.append(self.right_point.clone) - -cdef Point line_intersect(Edge e, float x): - cdef float y = e.slope * x + e.b - return Point(x, y) - -class Triangulator: - - def __init__(self, poly_line): - self.polygons = [] - self.edge_list = self.init_edges(poly_line) - self.trapezoids = [] - self.trapezoidal_map = TrapezoidalMap() - self.bounding_box = self.trapezoidal_map.bounding_box(self.edge_list) - self.query_graph = QueryGraph(isink(self.bounding_box)) - self.xmono_poly = [] - - self.process() - - def trapezoidMap(self): - return self.trapezoidal_map.map - - # Build the trapezoidal map and query graph - def process(self): - - for e in self.edge_list: - traps = self.query_graph.follow_edge(e) - for t in traps: - try: - self.trapezoidal_map.map.remove(t) - except: - pass - for t in traps: - tlist = [] - cp = t.contains(e.p) - cq = t.contains(e.q) - if cp and cq: - tlist = self.trapezoidal_map.case1(t, e) - self.query_graph.case1(t.sink, e, tlist) - elif cp and not cq: - tlist = self.trapezoidal_map.case2(t, e) - self.query_graph.case2(t.sink, e, tlist) - elif not cp and not cq: - tlist = self.trapezoidal_map.case3(t, e) - self.query_graph.case3(t.sink, e, tlist) - else: - tlist = self.trapezoidal_map.case4(t, e) - self.query_graph.case4(t.sink, e, tlist) - # Add new trapezoids to map - for t in tlist: - self.trapezoidal_map.map.append(t) - self.trapezoidal_map.clear() - - # Mark outside trapezoids - for t in self.trapezoidal_map.map: - self.mark_outside(t) - - # Collect interior trapezoids - for t in self.trapezoidal_map.map: - if t.inside: - self.trapezoids.append(t) - t.add_points() - - self.create_mountains() - - def mono_polies(self): - polies = [] - for x in self.xmono_poly: - polies.append(x.monoPoly) - return polies - - def create_mountains(self): - for s in self.edge_list: - if len(s.mpoints) > 0: - mountain = MonotoneMountain() - print s.mpoints - k = merge_sort(s.mpoints) - points = [s.p] + k + [s.q] - for p in points: - mountain.append(p) - mountain.process() - for t in mountain.triangles: - self.polygons.append(t) - self.xmono_poly.append(mountain) - - def mark_outside(self, t): - if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom: - t.trim_neighbors() - - def init_edges(self, points): - edges = [] - for i in range(len(points)-1): - p = Point(points[i][0], points[i][1]) - q = Point(points[i+1][0], points[i+1][1]) - edges.append(Edge(p, q)) - p = Point(points[0][0], points[0][1]) - q = Point(points[-1][0], points[-1][1]) - edges.append(Edge(p, q)) - return self.order_edges(edges) - - def order_edges(self, edges): - segs = [] - for s in edges: - p = self.shearTransform(s.p) - q = self.shearTransform(s.q) - if p.x > q.x: - segs.append(Edge(q, p)) - elif p.x < q.x: - segs.append(Edge(p, q)) - shuffle(segs) - return segs - - def shearTransform(self, point): - return Point(point.x + 1e-4 * point.y, point.y) - -cdef list merge_sort(l): - cdef list lleft, lright - cdef int p1, p2, p - if len(l)>1 : - lleft = merge_sort(l[:len(l)/2]) - lright = merge_sort(l[len(l)/2:]) - p1, p2, p = 0, 0, 0 - while p1 max.x: max = Point(e.p.x + margin, max.y) - if e.p.y > max.y: max = Point(max.x, e.p.y + margin) - if e.q.x > max.x: max = Point(e.q.x + margin, max.y) - if e.q.y > max.y: max = Point(max.x, e.q.y + margin) - if e.p.x < min.x: min = Point(e.p.x - margin, min.y) - if e.p.y < min.y: min = Point(min.x, e.p.y - margin) - if e.q.x < min.x: min = Point(e.q.x - margin, min.y) - if e.q.y < min.y: min = Point(min.x, e.q.y - margin) - top = Edge(Point(min.x, max.y), Point(max.x, max.y)) - bottom = Edge(Point(min.x, min.y), Point(max.x, min.y)) - left = bottom.p - right = top.q - return Trapezoid(left, right, top, bottom) - -cdef class Node: - - cdef Node left, right - cdef object parent_list - - def __init__(self, Node left, Node right): - self.parent_list = [] - self.left = left - self.right = right - if left != None: - left.parent_list.append(self) - if right != None: - right.parent_list.append(self) - - property left: - def __get__(self): return self.left - def __set__(self, Node left): self.left = left - - property right: - def __get__(self): return self.right - def __set__(self, Node right): self.right = right - - property parent_list: - def __get__(self): return self.parent_list - - def replace(self, Node node): - for parent in node.parent_list: - if parent.left is node: - parent.left = self - else: - parent.right = self - self.parent_list += node.parent_list - -cdef class Sink(Node): - - cdef Trapezoid trapezoid - - def __init__(self, trapezoid): - self.trapezoid = trapezoid - super(Sink, self).__init__(None, None) - trapezoid.sink = self - - property trapezoid: - def __get__(self): return self.trapezoid - - def locate(self, e): - return self - -cdef Sink isink(Trapezoid trapezoid): - if trapezoid.sink != None: - return trapezoid.sink - return Sink(trapezoid) - -cdef class XNode(Node): - - cdef Point point - - def __init__(self, Point point, Node lchild, Node rchild): - super(XNode, self).__init__(lchild, rchild) - self.point = point - - def locate(self, Edge e): - if e.p.x >= self.point.x: - return self.right.locate(e) - return self.left.locate(e) - -cdef class YNode(Node): - - cdef Edge edge - - def __init__(self, Edge edge, Node lchild, Node rchild): - super(YNode, self).__init__(lchild, rchild) - self.edge = edge - - def locate(self, Edge e): - if self.edge.is_above(e.p): - return self.right.locate(e) - elif self.edge.is_below(e.p): - return self.left.locate(e) - else: - if e.slope < self.edge.slope: - return self.right.locate(e) - else: - return self.left.locate(e) - -cdef class QueryGraph: - - cdef Node head - - def __init__(self, Node head): - self.head = head - - def locate(self, Edge e): - return self.head.locate(e).trapezoid - - def follow_edge(self, Edge e): - trapezoids = [self.locate(e)] - cdef int j = 0 - while(e.q.x > trapezoids[j].right_point.x): - if e.is_above(trapezoids[j].right_point): - trapezoids.append(trapezoids[j].upper_right) - else: - trapezoids.append(trapezoids[j].lower_right) - j += 1 - return trapezoids - - def replace(self, Sink sink, Node node): - if not sink.parent_list: - self.head = node - else: - node.replace(sink) - - def case1(self, Sink sink, Edge e, tlist): - cdef Node yNode = YNode(e, isink(tlist[1]), isink(tlist[2])) - cdef Node qNode = XNode(e.q, yNode, isink(tlist[3])) - cdef Node pNode = XNode(e.p, isink(tlist[0]), qNode) - self.replace(sink, pNode) - - def case2(self, Sink sink, Edge e, tlist): - yNode = YNode(e, isink(tlist[1]), isink(tlist[2])) - pNode = XNode(e.p, isink(tlist[0]), yNode) - self.replace(sink, pNode) - - def case3(self, Sink sink, Edge e, tlist): - yNode = YNode(e, isink(tlist[0]), isink(tlist[1])) - self.replace(sink, yNode) - - def case4(self, Sink sink, Edge e, tlist): - yNode = YNode(e, isink(tlist[0]), isink(tlist[1])) - qNode = XNode(e.q, yNode, isink(tlist[2])) - self.replace(sink, qNode) - -cdef float PI_SLOP = 3.1 - -cdef class MonotoneMountain: - - cdef: - Point tail, head - int size - list convex_points - list mono_poly - list triangles - list convex_polies - bool positive - - def __init__(self): - self.size = 0 - self.tail = None - self.head = None - self.positive = False - self.convex_points = [] - self.mono_poly = [] - self.triangles = [] - self.convex_polies = [] - - def append(self, Point point): - if self.size == 0: - self.head = point - self.size += 1 - elif self.size == 1: - if point.not_equal(self.head): - self.tail = point - self.tail.prev = self.head - self.head.next = self.tail - self.size += 1 - else: - if point.not_equal(self.tail): - self.tail.next = point - point.prev = self.tail - self.tail = point - self.size += 1 - - cdef void remove(self, Point point): - cdef Point next, prev - next = point.next - prev = point.prev - point.prev.next = next - point.next.prev = prev - self.size -= 1 - - def process(self): - self.positive = self.angle_sign() - self.gen_mono_poly() - p = self.head.next - while p != self.tail: - a = self.angle(p) - if a >= PI_SLOP or a <= -PI_SLOP: self.remove(p) - elif self.is_convex(p): self.convex_points.append(p) - p = p.next - self.triangulate() - - cdef void triangulate(self): - while not len(self.convex_points) > 0: - ear = self.convex_points.remove(0) - a = ear.prev - b = ear - c = ear.next - triangle = [a, b, c] - self.triangles.append(triangle) - self.remove(ear) - if self.valid(a): self.convex_points.append(a) - if self.valid(c): self.convex_points.append(c) - assert(self.size <= 3, "Triangulation bug, please report") - - cdef bool valid(self, Point p): - return p != self.head and p != self.tail and self.is_convex(p) - - cdef void gen_mono_poly(self): - cdef Point p = self.head - while(p != None): - self.mono_poly.append(p) - p = p.next - - cdef float angle(self, Point p): - cdef Point a = p.next - p - cdef Point b = p.prev - p - return atan2(a.cross(b), a.dot(b)) - - cdef float angle_sign(self): - cdef Point a = self.head.next - self.head - cdef Point b = self.tail - self.head - return atan2(a.cross(b), a.dot(b)) >= 0 - - cdef bool is_convex(self, Point p): - if self.positive != (self.angle(p) >= 0): return False - return True diff --git a/python/p2t.sh b/python/p2t.sh deleted file mode 100644 index 67dd588..0000000 --- a/python/p2t.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -python -O poly2tri.py diff --git a/python/poly2tri.py b/python/poly2tri.py deleted file mode 100644 index e0818ed..0000000 --- a/python/poly2tri.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env python2.6 -from framework import Game, draw_polygon, reset_zoom, draw_line, decompose_poly, make_ccw, Triangulator - -class Poly2Tri(Game): - - screen_size = 800.0, 600.0 - - dude = [[174.50415,494.59368],[215.21844,478.87939],[207.36129,458.87939],[203.07558,441.02225],[203.07558,418.1651], - [210.93272,394.59367],[224.50415,373.1651],[241.64701,358.1651],[257.36129,354.59367],[275.93272,356.73653], - [293.07558,359.59367],[309.50415,377.45082],[322.36129,398.1651],[331.64701,421.73653],[335.21844,437.45082], - [356.64701,428.52225],[356.1113,428.34367],[356.1113,428.34367],[368.78987,419.59368],[349.50415,384.59367], - [323.78987,359.59367],[290.93272,343.87939],[267.36129,341.02225],[264.50415,331.02225],[264.50415,321.02225], - [268.78987,306.02225],[285.93272,286.02225],[295.21844,270.30796],[303.78987,254.59367],[306.64701,213.87939], - [320,202.36218],[265,202.36218],[286.64701,217.45082],[293.78987,241.02225],[285,257.36218],[270.93272,271.73653], - [254.50415,266.02225],[250.93272,248.1651],[256.64701,233.1651],[256.64701,221.02225],[245.93272,215.30796], - [238.78987,216.73653],[233.78987,232.45082],[232.36129,249.59367],[243.07558,257.09367],[242.89701,270.30796], - [235.93272,279.95082],[222.36129,293.1651],[205.21844,300.6651],[185,297.36218],[170,242.36218],[175,327.36218], - [185,322.36218],[195,317.36218],[230.75415,301.02225],[235.39701,312.45082],[240.57558,323.52225], - [243.61129,330.48653],[245.21844,335.12939],[245.03987,344.4151],[229.86129,349.4151],[209.14701,362.09367], - [192.89701,377.80796],[177.18272,402.27225],[172.36129,413.87939],[169.14701,430.48653],[168.61129,458.52225], - [168.61129,492.80796]] - - test = [[235.04275999999999, 739.07534999999996], [218.13066000000001, 719.73902999999996], - [218.15215000000001, 709.96821], [218.17362, 700.19740000000002], [243.15215000000001, 685.27858000000003], - [268.13065, 670.35974999999996], [268.13065, 660.81429000000003], [268.13065, 651.26882999999998], - [314.55921999999998, 651.26882999999998], [360.98779000000002, 651.26882999999998], - [360.98683999999997, 666.44740000000002], [360.98046561000007, 669.27438118000009], - [360.96234088000011,672.68539864000013], [360.93345946999995, 676.58895225999993], - [360.89481504000003, 680.89354191999996], [360.84740125000002, 685.50766749999991], - [360.79221175999999, 690.33982888000003], [360.73024022999999, 695.29852593999999], - [360.66248032000004, 700.29225856000005], [360.58992569000003, 705.22952662000012], - [360.51357000000002, 710.01882999999998], [360.04131999999998, 738.41168000000005], - [310.51454999999999, 738.41168000000005], [260.98779999999999, 738.41168000000005], - [260.98779999999999, 748.41168000000005], [260.98779999999999, 758.41168000000005], - [256.47133000000002, 758.41168000000005], [251.95484999999999, 758.41168000000005]] - - test2 = [[101.25, 1006.8145], [-0.0, 869.65629999999999], [0.012800000000000001, 630.57820000000004], - [0.025600000000000001, 391.5], [13.7628, 385.74239999999998], [20.536000000000001, 382.96260000000001], - [26.871200000000002, 380.49279999999999],[32.864100000000001, 378.30540000000002], - [38.610700000000001, 376.37279999999998], [44.206600000000002, 374.66730000000001], - [49.747799999999998, 373.16129999999998], [55.329900000000002, 371.82709999999997], - [61.0488, 370.63720000000001],[67.000299999999996, 369.56400000000002], [73.280299999999997, 368.5797], - [77.521299999999997, 368.07459999999998], [82.578500000000005, 367.66539999999998], - [88.263199999999998, 367.35390000000001], [94.386899999999997, 367.14170000000001], - [100.7611, 367.0308], [107.1972, 367.02269999999999], [113.5067, 367.11930000000001], - [119.5009, 367.32229999999998], [124.9913, 367.63339999999999], [129.7894, 368.05450000000002], - [136.77860000000001, 368.94200000000001], [143.9999, 370.10390000000001], [151.3793, 371.52069999999998], - [158.84270000000001, 373.17270000000002], [166.3159, 375.04050000000001], [173.72499999999999, 377.10449999999997], - [180.9957, 379.34500000000003], [188.0539, 381.74250000000001], [194.82570000000001, 384.27749999999997], - [201.23679999999999, 386.93029999999999], [212.5, 391.83980000000003], [212.08760000000001, 550.41989999999998], - [211.67509999999999, 709.0], [274.00200000000001, 709.0], [336.3288, 709.0], [335.66520000000003, 636.25], - [335.55739999999997, 623.91790000000003], [335.45409999999998, 611.09199999999998], [335.3569, 598.0163], - [335.267, 584.93499999999995], [335.18599999999998, 572.09220000000005], [335.11540000000002, 559.73199999999997], - [335.0566, 548.09860000000003], [335.0111, 537.43600000000004], [334.98039999999997, 527.98839999999996], - [334.96589999999998, 520.0], [334.93029999999999, 476.5], [264.0222, 418.0], [193.114, 359.5], - [193.05699999999999, 295.4984], [193.0, 231.49680000000001], [308.7516, 115.7484], [424.50319999999999, 0.0], - [430.71390000000002, -0.0], [436.9246, -0.0], [458.9753, 20.0], [481.02589999999998, 40.0], - [558.38530000000003, 40.0], [635.74469999999997, 40.0], [660.50120000000004, 19.9588], - [685.25779999999997, -0.082400000000000001], [692.0471, 0.20880000000000001], - [698.8365, 0.5], [809.42550000000006, 115.9161], [920.01459999999997, 231.3321], [919.75729999999999, 295.3526], - [919.5, 359.37310000000002], [850.31790000000001, 416.4366], [781.13589999999999, 473.5], - [781.06790000000001, 593.7577], [781.0, 714.0154], [842.25, 713.7577], [903.5, 713.5], [903.5, 552.5], [903.5, 391.5], - [915.5, 386.2894], [925.01319999999998, 382.34390000000002], [934.29579999999999, 378.88010000000003], - [943.42060000000004, 375.8827], [952.46050000000002,373.33629999999999], [961.48839999999996, 371.22570000000002], - [970.57719999999995, 369.53559999999999], [979.79989999999998, 368.25069999999999], - [989.22929999999997, 367.35570000000001], [998.9384, 366.83539999999999], [1009.0, 366.67430000000002], - [1018.876, 366.87939999999998], [1028.7419, 367.4649], [1038.5688, 368.42529999999999], - [1048.3277, 369.75490000000002], [1057.9897000000001, 371.44799999999998], [1067.5259000000001, 373.49900000000002], - [1076.9074000000001, 375.90219999999999], [1086.1052, 378.65210000000002], [1095.0904, 381.74290000000002], - [1103.8340000000001, 385.16899999999998], [1105.4327000000001, 385.83539999999999], - [1107.0215000000001, 386.49689999999998], [1108.5744999999999, 387.1429], [1110.0654999999999, 387.76240000000001], - [1111.4684, 388.34469999999999], [1112.7573, 388.87900000000002], [1113.9059, 389.3544], - [1114.8883000000001, 389.76010000000002], [1115.6784, 390.08530000000002], [1116.25, 390.3193], - [1119.0, 391.43849999999998], [1118.9577999999999, 633.4692], [1118.9155000000001, 875.5],[1016.0895, 1009.5], - [913.26340000000005, 1143.5], [908.63170000000002, 1143.8047999999999], [904.0, 1144.1096], [904.0, 993.0548], - [904.0, 842.0], [842.5, 842.0], [781.0, 842.0], [781.0, 918.5], [781.0, 995.0], [758.5, 995.0], - [753.20910000000003, 995.00739999999996], [748.79459999999995, 995.03269999999998], - [745.18129999999996, 995.08109999999999], [742.29399999999998, 995.15729999999996], - [740.05730000000005, 995.26639999999998], [738.39599999999996, 995.41330000000005], - [737.23490000000004, 995.60289999999998], [736.49869999999999, 995.84010000000001], - [736.11210000000005, 996.13], [736.0, 996.47739999999999], [736.09749999999997, 996.82140000000004], - [736.42740000000003, 997.11329999999998], [737.04610000000002, 997.3587], [738.01009999999997, 997.56290000000001], - [739.37559999999996, 997.73140000000001], [741.19910000000004, 997.86959999999999], [743.53679999999997, 997.9828], - [746.44510000000002, 998.07659999999998], [749.98040000000003,998.15629999999999], - [754.19910000000004, 998.22739999999999], [772.39829999999995, 998.5], [823.72850000000005, 1071.0], - [875.05859999999996, 1143.5], [558.86419999999998, 1143.7516000000001], [507.74619999999999, 1143.787], - [459.17950000000002, 1143.8106], [413.82889999999998, 1143.8226], [372.35939999999999, 1143.8232], - [335.43560000000002, 1143.8130000000001], [303.7226, 1143.7919999999999], [277.88499999999999, 1143.7606000000001], - [258.58789999999999, 1143.7192], [246.49590000000001, 1143.6679999999999], [242.2739, 1143.6072999999999], - [244.95830000000001, 1139.4844000000001], [252.41210000000001, 1128.4439], [263.45999999999998, 1112.2019], - [276.92660000000001, 1092.4740999999999], [291.63650000000001, 1070.9766], [306.41430000000003, 1049.4251999999999], - [320.0847, 1029.5360000000001], [331.47219999999999, 1013.0247000000001], [339.4015, 1001.6074], - [342.69729999999998, 997.0], [342.98259999999999, 996.91470000000004], [343.6619, 996.82510000000002], - [344.70080000000002, 996.7328], [346.06450000000001, 996.63959999999997], [347.71870000000001, 996.54729999999995], - [349.62880000000001, 996.45770000000005], [351.76029999999997, 996.37249999999995], - [354.07859999999999, 996.29349999999999], [356.54919999999998, 996.22249999999997], [359.1377, 996.16110000000003], - [363.04469999999998, 996.07169999999996], [366.26229999999998, 995.97929999999997], - [368.85410000000002, 995.87580000000003], [370.88319999999999, 995.75319999999999], - [372.41320000000002, 995.60320000000002], [373.50729999999999,995.41790000000003], - [374.22899999999998, 995.18920000000003], [374.64159999999998, 994.90880000000004], - [374.80860000000001, 994.56889999999999], [374.79329999999999, 994.16110000000003], - [374.63619999999997, 993.7568], [374.2833, 993.4194], [373.65809999999999, 993.14160000000004], - [372.6841, 992.91570000000002], [371.28500000000003, 992.73419999999999], [369.3843, 992.58960000000002], - [366.90559999999999, 992.47429999999997], [363.77249999999998, 992.38059999999996], - [359.90839999999997, 992.30119999999999], [355.2371, 992.22839999999997], [336.0, 991.95680000000004], - [336.0, 914.97839999999997], [336.0, 838.0], [274.0, 838.0], [212.0, 838.0], [212.0, 991.0], [212.0, 1144.0], - [207.25, 1143.9864], [202.5, 1143.9727]] - - def __init__(self): - super(Poly2Tri, self).__init__(*self.screen_size) - - # Load point set - file_name = "../data/dude.dat" - self.points = self.load_points(file_name) - - # Triangulate - t1 = self.time - seidel = Triangulator(self.points) - dt = (self.time - t1) * 1000.0 - - self.triangles = seidel.triangles() - #self.trapezoids = seidel.trapezoids - self.trapezoids = seidel.trapezoidal_map.map - self.edges = seidel.edge_list - print "time (ms) = %f , num triangles = %d" % (dt, len(self.triangles)) - - for p in self.dude: - p[0] -= 75 - - make_ccw(self.dude) - self.decomp_poly = [] - t1 = self.time - decompose_poly(self.dude, self.decomp_poly) - dt = (self.time - t1) * 1000.0 - print "time (ms) = %f , num polies = %d" % (dt, len(self.decomp_poly)) - - self.main_loop() - - def update(self): - pass - - def render(self): - reset_zoom(2.0, (300, 450), self.screen_size) - red = 255, 0, 0 - yellow = 255, 255, 0 - green = 0, 255, 0 - for t in self.triangles: - draw_polygon(t, red) - - for p in self.decomp_poly: - draw_polygon(p, red) - - ''' - for t in self.trapezoids: - verts = self.trapezoids[t].vertices() - #verts = t.vertices() - draw_polygon(verts, yellow) - ''' - for e in self.edges: - p1 = e.p.x, e.p.y - p2 = e.q.x, e.q.y - draw_line(p1, p2, green) - - - def load_points(self, file_name): - infile = open(file_name, "r") - points = [] - while infile: - line = infile.readline() - s = line.split() - if len(s) == 0: - break - points.append((float(s[0]), float(s[1]))) - return points - -if __name__ == '__main__': - demo = Poly2Tri() \ No newline at end of file diff --git a/python/seidel.py b/python/seidel.py deleted file mode 100644 index 98daecb..0000000 --- a/python/seidel.py +++ /dev/null @@ -1,627 +0,0 @@ -# -# Poly2Tri -# Copyright (c) 2009, Mason Green -# http://code.google.com/p/poly2tri/ -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, -# self list of conditions and the following disclaimer. -# Redistributions in binary form must reproduce the above copyright notice, -# self list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# Neither the name of Poly2Tri nor the names of its contributors may be -# used to endorse or promote products derived from self software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -from random import shuffle -from math import atan2 - -## -## Based on Raimund Seidel'e paper "A simple and fast incremental randomized -## algorithm for computing trapezoidal decompositions and for triangulating polygons" -## (Ported from poly2tri) -## - -# Shear transform. May effect numerical robustness -SHEAR = 1e-6 - -class Point(object): - - def __init__(self, x, y): - self.x = x - self.y = y - self.next, self.prev = None, None - - def __sub__(self, other): - if isinstance(other, Point): - return Point(self.x - other.x, self.y - other.y) - else: - return Point(self.x - other, self.y - other) - - def __add__(self, other): - if isinstance(other, Point): - return Point(self.x + other.x, self.y + other.y) - else: - return Point(self.x + other, self.y + other) - - def __mul__(self, f): - return Point(self.x * f, self.y * f) - - def __div__(self, a): - return Point(self.x / a, self.y / a) - - def cross(self, p): - return self.x * p.y - self.y * p.x - - def dot(self, p): - return self.x * p.x + self.y * p.y - - def length(self): - return sqrt(self.x * self.x + self.y * self.y) - - def normalize(self): - return self / self.length() - - def less(self, p): - return self.x < p.x - - def neq(self, other): - return other.x != self.x or other.y != self.y - - def clone(self): - return Point(self.x, self.y) - -class Edge(object): - - def __init__(self, p, q): - self.p = p - self.q = q - self.slope = (q.y - p.y) / (q.x - p.x) - self.b = p.y - (p.x * self.slope) - self.above, self.below = None, None - self.mpoints = [] - self.mpoints.append(p) - self.mpoints.append(q) - - ## - ## NOTE Rounding accuracy significantly effects numerical robustness!!! - ## - - def is_above(self, point): - return (round(point.y, 2) < round(self.slope * point.x + self.b, 2)) - - def is_below(self, point): - return (round(point.y, 2) > round(self.slope * point.x + self.b, 2)) - - def intersect(self, c, d): - a = self.p - b = self.q - a1 = self.signed_area(a, b, d) - a2 = self.signed_area(a, b, c) - if a1 != 0.0 and a2 != 0.0 and (a1 * a2) < 0.0: - a3 = self.signed_area(c, d, a) - a4 = a3 + a2 - a1 - if a3 * a4 < 0.0: - t = a3 / (a3 - a4) - return a + ((b - a) * t) - return 0.0 - - def signed_area(self, a, b, c): - return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x) - -class Trapezoid(object): - - def __init__(self, left_point, right_point, top, bottom): - self.left_point = left_point - self.right_point = right_point - self.top = top - self.bottom = bottom - self.upper_left = None - self.upper_right = None - self.lower_left = None - self.lower_right = None - self.inside = True - self.sink = None - self.key = hash(self) - - def update_left(self, ul, ll): - self.upper_left = ul - if ul != None: ul.upper_right = self - self.lower_left = ll - if ll != None: ll.lower_right = self - - def update_right(self, ur, lr): - self.upper_right = ur - if ur != None: ur.upper_left = self - self.lower_right = lr - if lr != None: lr.lower_left = self - - def update_left_right(self, ul, ll, ur, lr): - self.upper_left = ul - if ul != None: ul.upper_right = self - self.lower_left = ll - if ll != None: ll.lower_right = self - self.upper_right = ur - if ur != None: ur.upper_left = self - self.lower_right = lr - if lr != None: lr.lower_left = self - - def trim_neighbors(self): - if self.inside: - self.inside = False - if self.upper_left != None: self.upper_left.trim_neighbors() - if self.lower_left != None: self.lower_left.trim_neighbors() - if self.upper_right != None: self.upper_right.trim_neighbors() - if self.lower_right != None: self.lower_right.trim_neighbors() - - def contains(self, point): - return (point.x > self.left_point.x and point.x < self.right_point.x and - self.top.is_above(point) and self.bottom.is_below(point)) - - def vertices(self): - v1 = line_intersect(self.top, self.left_point.x) - v2 = line_intersect(self.bottom, self.left_point.x) - v3 = line_intersect(self.bottom, self.right_point.x) - v4 = line_intersect(self.top, self.right_point.x) - return v1, v2, v3, v4 - - def add_points(self): - if self.left_point != self.bottom.p: - self.bottom.mpoints.append(self.left_point.clone()) - if self.right_point != self.bottom.q: - self.bottom.mpoints.append(self.right_point.clone()) - if self.left_point != self.top.p: - self.top.mpoints.append(self.left_point.clone()) - if self.right_point != self.top.q: - self.top.mpoints.append(self.right_point.clone()) - -def line_intersect(edge, x): - y = edge.slope * x + edge.b - return x, y - -class Triangulator(object): - - ## - ## Number of points should be > 3 - ## - def __init__(self, poly_line): - self.polygons = [] - self.trapezoids = [] - self.xmono_poly = [] - self.edge_list = self.init_edges(poly_line) - self.trapezoidal_map = TrapezoidalMap() - self.bounding_box = self.trapezoidal_map.bounding_box(self.edge_list) - self.query_graph = QueryGraph(isink(self.bounding_box)) - - self.process() - - def triangles(self): - triangles = [] - for p in self.polygons: - verts = [] - for v in p: - verts.append((v.x, v.y)) - triangles.append(verts) - return triangles - - def trapezoid_map(self): - return self.trapezoidal_map.map - - # Build the trapezoidal map and query graph - def process(self): - for edge in self.edge_list: - traps = self.query_graph.follow_edge(edge) - for t in traps: - # Remove old trapezods - del self.trapezoidal_map.map[t.key] - # Bisect old trapezoids and create new - cp = t.contains(edge.p) - cq = t.contains(edge.q) - if cp and cq: - tlist = self.trapezoidal_map.case1(t, edge) - self.query_graph.case1(t.sink, edge, tlist) - elif cp and not cq: - tlist = self.trapezoidal_map.case2(t, edge) - self.query_graph.case2(t.sink, edge, tlist) - elif not cp and not cq: - tlist = self.trapezoidal_map.case3(t, edge) - self.query_graph.case3(t.sink, edge, tlist) - else: - tlist = self.trapezoidal_map.case4(t, edge) - self.query_graph.case4(t.sink, edge, tlist) - # Add new trapezoids to map - for t in tlist: - self.trapezoidal_map.map[t.key] = t - self.trapezoidal_map.clear() - - # Mark outside trapezoids w/ depth-first search - for k, t in self.trapezoidal_map.map.items(): - self.mark_outside(t) - - # Collect interior trapezoids - for k, t in self.trapezoidal_map.map.items(): - if t.inside: - self.trapezoids.append(t) - t.add_points() - - # Generate the triangles - self.create_mountains() - - def mono_polies(self): - polies = [] - for x in self.xmono_poly: - polies.append(x.monoPoly) - return polies - - def create_mountains(self): - for edge in self.edge_list: - if len(edge.mpoints) > 2: - mountain = MonotoneMountain() - points = merge_sort(edge.mpoints) - for p in points: - mountain.add(p) - mountain.process() - for t in mountain.triangles: - self.polygons.append(t) - self.xmono_poly.append(mountain) - - def mark_outside(self, t): - if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom: - t.trim_neighbors() - - def init_edges(self, points): - edge_list = [] - size = len(points) - for i in range(size): - j = i + 1 if i < size-1 else 0 - p = points[i][0], points[i][1] - q = points[j][0], points[j][1] - edge_list.append((p, q)) - return self.order_edges(edge_list) - - def order_edges(self, edge_list): - edges = [] - for e in edge_list: - p = shear_transform(e[0]) - q = shear_transform(e[1]) - if p.x > q.x: - edges.append(Edge(q, p)) - else: - edges.append(Edge(p, q)) - # Randomized incremental algorithm - shuffle(edges) - return edges - -def shear_transform(point): - return Point(point[0] + SHEAR * point[1], point[1]) - -def merge_sort(l): - if len(l)>1 : - lleft = merge_sort(l[:len(l)/2]) - lright = merge_sort(l[len(l)/2:]) - p1, p2, p = 0, 0, 0 - while p1 max.x: max = Point(e.p.x + margin, max.y) - if e.p.y > max.y: max = Point(max.x, e.p.y + margin) - if e.q.x > max.x: max = Point(e.q.x + margin, max.y) - if e.q.y > max.y: max = Point(max.x, e.q.y + margin) - if e.p.x < min.x: min = Point(e.p.x - margin, min.y) - if e.p.y < min.y: min = Point(min.x, e.p.y - margin) - if e.q.x < min.x: min = Point(e.q.x - margin, min.y) - if e.q.y < min.y: min = Point(min.x, e.q.y - margin) - top = Edge(Point(min.x, max.y), Point(max.x, max.y)) - bottom = Edge(Point(min.x, min.y), Point(max.x, min.y)) - left = top.p - right = top.q - trap = Trapezoid(left, right, top, bottom) - self.map[trap.key] = trap - return trap - -class Node(object): - - def __init__(self, lchild, rchild): - self.parent_list = [] - self.lchild = lchild - self.rchild = rchild - if lchild != None: - lchild.parent_list.append(self) - if rchild != None: - rchild.parent_list.append(self) - - def replace(self, node): - for parent in node.parent_list: - if parent.lchild is node: - parent.lchild = self - else: - parent.rchild = self - self.parent_list += node.parent_list - -class Sink(Node): - - def __init__(self, trapezoid): - super(Sink, self).__init__(None, None) - self.trapezoid = trapezoid - trapezoid.sink = self - - def locate(self, edge): - return self - -def isink(trapezoid): - if trapezoid.sink is None: - return Sink(trapezoid) - return trapezoid.sink - -class XNode(Node): - - def __init__(self, point, lchild, rchild): - super(XNode, self).__init__(lchild, rchild) - self.point = point - - def locate(self, edge): - if edge.p.x >= self.point.x: - return self.rchild.locate(edge) - return self.lchild.locate(edge) - -class YNode(Node): - - def __init__(self, edge, lchild, rchild): - super(YNode, self).__init__(lchild, rchild) - self.edge = edge - - def locate(self, edge): - if self.edge.is_above(edge.p): - return self.rchild.locate(edge) - if self.edge.is_below(edge.p): - return self.lchild.locate(edge) - if edge.slope < self.edge.slope: - return self.rchild.locate(edge) - return self.lchild.locate(edge) - -class QueryGraph: - - def __init__(self, head): - self.head = head - - def locate(self, edge): - return self.head.locate(edge).trapezoid - - def follow_edge(self, edge): - trapezoids = [self.locate(edge)] - while(edge.q.x > trapezoids[-1].right_point.x): - if edge.is_above(trapezoids[-1].right_point): - trapezoids.append(trapezoids[-1].upper_right) - else: - trapezoids.append(trapezoids[-1].lower_right) - return trapezoids - - def replace(self, sink, node): - if sink.parent_list: - node.replace(sink) - else: - self.head = node - - def case1(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[1]), isink(tlist[2])) - qNode = XNode(edge.q, yNode, isink(tlist[3])) - pNode = XNode(edge.p, isink(tlist[0]), qNode) - self.replace(sink, pNode) - - def case2(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[1]), isink(tlist[2])) - pNode = XNode(edge.p, isink(tlist[0]), yNode) - self.replace(sink, pNode) - - def case3(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[0]), isink(tlist[1])) - self.replace(sink, yNode) - - def case4(self, sink, edge, tlist): - yNode = YNode(edge, isink(tlist[0]), isink(tlist[1])) - qNode = XNode(edge.q, yNode, isink(tlist[2])) - self.replace(sink, qNode) - -PI_SLOP = 3.1 - -class MonotoneMountain: - - def __init__(self): - self.size = 0 - self.tail = None - self.head = None - self.positive = False - self.convex_points = [] - self.mono_poly = [] - self.triangles = [] - self.convex_polies = [] - - def add(self, point): - if self.size is 0: - self.head = point - self.size = 1 - elif self.size is 1: - if point.neq(self.head): - self.tail = point - self.tail.prev = self.head - self.head.next = self.tail - self.size = 2 - else: - if point.neq(self.tail): - self.tail.next = point - point.prev = self.tail - self.tail = point - self.size += 1 - - def remove(self, point): - next = point.next - prev = point.prev - point.prev.next = next - point.next.prev = prev - self.size -= 1 - - def process(self): - self.positive = self.angle_sign() - self.gen_mono_poly() - p = self.head.next - while p != self.tail: - a = self.angle(p) - if a >= PI_SLOP or a <= -PI_SLOP or a == 0: - self.remove(p) - elif self.is_convex(p): - self.convex_points.append(p) - p = p.next - self.triangulate() - - def triangulate(self): - while self.convex_points: - ear = self.convex_points.pop(0) - a = ear.prev - b = ear - c = ear.next - triangle = (a, b, c) - self.triangles.append(triangle) - self.remove(ear) - if self.valid(a): - self.convex_points.append(a) - if self.valid(c): - self.convex_points.append(c) - #assert self.size <= 3, "Triangulation bug, please report" - - def valid(self, p): - return p != self.head and p != self.tail and self.is_convex(p) - - def gen_mono_poly(self): - p = self.head - while(p != None): - self.mono_poly.append(p) - p = p.next - - def angle(self, p): - a = p.next - p - b = p.prev - p - return atan2(a.cross(b), a.dot(b)) - - def angle_sign(self): - a = self.head.next - self.head - b = self.tail - self.head - return atan2(a.cross(b), a.dot(b)) >= 0 - - def is_convex(self, p): - if self.positive != (self.angle(p) >= 0): - return False - return True \ No newline at end of file diff --git a/python/setup.py b/python/setup.py deleted file mode 100644 index f48de47..0000000 --- a/python/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -import sys -import os - -from distutils.core import setup -from distutils.extension import Extension -from Cython.Distutils import build_ext - -# Usage: python setup.py build_ext --i - -version = '0.1' - -sourcefiles = ['framework/framework.pyx', 'framework/predicates.c'] - -# Platform-dependent submodules - -if sys.platform == 'win32': - # MS Windows - libs = ['glew32', 'glu32', 'glfw', 'opengl32'] -elif sys.platform == 'darwin': - # Apple OSX - raise SystemError('OSX is unsupported in this version') -else: - # GNU/Linux, BSD, etc - libs = ['GLEW', 'GLU', 'glfw', 'GL'] - -mod_engine = Extension( - "framework", - sourcefiles, - libraries = libs, - language = 'c' -) - -setup( - name = 'Poly2Tri', - version = version, - description = 'A 2D Polygon Triangulator', - author = 'Mason Green (zzzzrrr)', - author_email = '', - maintainer = '', - maintainer_email = '', - url = 'http://code.google.com/p/poly2tri/', - cmdclass = {'build_ext': build_ext}, - ext_modules = [mod_engine], -) \ No newline at end of file diff --git a/scala/src/org/poly2tri/Poly2Tri.scala b/scala/src/org/poly2tri/Poly2Tri.scala deleted file mode 100644 index 2e130fa..0000000 --- a/scala/src/org/poly2tri/Poly2Tri.scala +++ /dev/null @@ -1,467 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri - -import org.newdawn.slick.{BasicGame, GameContainer, Graphics, Color, AppGameContainer} -import org.newdawn.slick.geom.{Polygon, Circle} - -import scala.collection.mutable.ArrayBuffer -import scala.io.Source - -import seidel.Triangulator -import shapes.{Segment, Point, Triangle} -import earClip.EarClip -import cdt.CDT - -// TODO: Lots of documentation! -// : Add Hertel-Mehlhorn algorithm -object Poly2Tri { - - def main(args: Array[String]) { - val container = new AppGameContainer(new Poly2TriDemo()) - container.setDisplayMode(800,600,false) - container.start() - } - -} - -class Poly2TriDemo extends BasicGame("Poly2Tri") { - - object Algo extends Enumeration { - type Algo = Value - val CDT, Seidel, EarClip = Value - } - import Algo._ - - // Sedidel Triangulator - var seidel: Triangulator = null - var segments: ArrayBuffer[Segment] = null - var chestSegs: ArrayBuffer[Segment] = null - var headSegs: ArrayBuffer[Segment] = null - - // EarClip Triangulator - val earClip = new EarClip - var earClipResults: Array[poly2tri.earClip.Triangle] = null - - // Sweep Line Constraied Delauney Triangulator (CDT) - var slCDT: CDT = null - - var quit = false - var drawMap = false - var drawSegs = true - var drawCDTMesh = false - - val nazcaMonkey = "../data/nazca_monkey.dat" - val nazcaHeron = "../data/nazca_heron_old.dat" - val bird = "../data/bird.dat" - val snake = "../data/i.snake" - val star = "../data/star.dat" - val strange = "../data/strange.dat" - val i18 = "../data/i.18" - val tank = "../data/tank.dat" - val dude = "../data/dude.dat" - val basic = "../data/basic.dat" - - var currentModel = dude - var doCDT = true - // The current algorithm - var algo = CDT - - var mouseButton = 0 - var mousePressed = false - var mouseDrag = false - var mousePos = Point(0, 0) - var mousePosOld = Point(0, 0) - var deltaX = 0f - var deltaY = 0f - var scaleFactor = 0.85f - - var gameContainer: GameContainer = null - - def init(container: GameContainer) { - gameContainer = container - selectModel(currentModel) - } - - def update(gc: GameContainer, delta: Int) { - if(quit) gc exit - } - - def render(container: GameContainer, g: Graphics) { - - val red = new Color(1f, 0f,0.0f) - val blue = new Color(0f, 0f, 1f) - val green = new Color(0f, 1f, 0f) - val yellow = new Color(1f, 1f, 0f) - - g.setColor(green) - g.drawString("'1-9' to cycle models, mouse to pan & zoom", 10, 522) - g.drawString("'c,s,e' to switch CDT / Seidel / EarClip algos", 10, 537) - g.drawString("'t' to show trapezoidal map (Seidel)", 10, 552) - g.drawString("'m' to show triangle mesh (CDT)", 10, 567) - g.drawString("'d' to draw edges", 10, 582) - - g.scale(scaleFactor, scaleFactor) - g.translate(deltaX, deltaY) - - algo match { - - case Algo.Seidel => { - for(t <- seidel.polygons) { - val poly = new Polygon - t.foreach(p => poly.addPoint(p.x, p.y)) - g.setColor(red) - g.draw(poly) - } - if (drawMap) { - for(t <- seidel.trapezoidMap) { - val polygon = new Polygon() - for(v <- t.vertices) { - polygon.addPoint(v.x, v.y) - } - g.setColor(red) - g.draw(polygon) - }/* - for(mp <- seidel.monoPolies) { - val poly = new Polygon - mp.foreach(p => poly.addPoint(p.x, p.y)) - g.setColor(yellow) - g.draw(poly) - }*/ - } - } - - case Algo.EarClip => { - earClipResults.foreach(t => { - val triangle = new Polygon - triangle.addPoint(t.x(0), t.y(0)) - triangle.addPoint(t.x(1), t.y(1)) - triangle.addPoint(t.x(2), t.y(2)) - g.setColor(red) - g.draw(triangle) - }) - } - - case Algo.CDT => { - val draw = if(drawCDTMesh) slCDT.triangleMesh else slCDT.triangles - draw.foreach( t => { - val triangle = new Polygon - triangle.addPoint(t.points(0).x, t.points(0).y) - triangle.addPoint(t.points(1).x, t.points(1).y) - triangle.addPoint(t.points(2).x, t.points(2).y) - g.setColor(red) - g.draw(triangle) - }) - - slCDT.debugTriangles.foreach( t => { - val triangle = new Polygon - triangle.addPoint(t.points(0).x, t.points(0).y) - triangle.addPoint(t.points(1).x, t.points(1).y) - triangle.addPoint(t.points(2).x, t.points(2).y) - g.setColor(blue) - g.draw(triangle) - }) - - for(i <- 0 until slCDT.cList.size) { - val circ = new Circle(slCDT.cList(i).x, slCDT.cList(i).y, 0.5f) - g.setColor(blue); g.draw(circ); g.fill(circ) - } - - } - - case _ => - } - - if(drawSegs) { - g.setColor(green) - for(i <- 0 until segments.size) { - val s = segments(i) - g.drawLine(s.p.x,s.p.y,s.q.x,s.q.y) - } - } - - if(currentModel == "../data/dude.dat" && drawSegs) { - g.setColor(green) - for(i <- 0 until chestSegs.size) { - val s = chestSegs(i) - g.drawLine(s.p.x,s.p.y,s.q.x,s.q.y) - } - for(i <- 0 until headSegs.size) { - val s = headSegs(i) - g.drawLine(s.p.x,s.p.y,s.q.x,s.q.y) - } - } - - } - - /** - * Handle mouseDown events. - * @param p The screen location that the mouse is down at. - */ - override def mousePressed(b: Int, x: Int, y: Int) { - - mouseButton = b - mousePressed = true - mousePosOld = mousePos - mousePos = Point(x, y) - - // Right click - // Correctly adjust for pan and zoom - if(mouseButton == 1) { - val point = mousePos/scaleFactor + Point(deltaX, deltaY) - println(point) - slCDT.addPoint(point) - slCDT.triangulate - } - - } - - /** - * Handle mouseUp events. - */ - override def mouseReleased(b: Int, x: Int, y: Int) { - mousePosOld = mousePos - mousePos = Point(x,y) - mousePressed = false - } - - /** - * Handle mouseMove events (TestbedMain also sends mouseDragged events here) - * @param p The new mouse location (screen coordinates) - */ - override def mouseMoved(oldX: Int, oldY: Int, x: Int, y: Int) { - mousePosOld = mousePos - mousePos = Point(x,y) - if(mousePressed) { - deltaX += mousePos.x - mousePosOld.x - deltaY += mousePos.y - mousePosOld.y - } - } - - override def mouseWheelMoved(notches: Int) { - if (notches < 0) { - scaleFactor = Math.min(300f, scaleFactor * 1.05f); - } - else if (notches > 0) { - scaleFactor = Math.max(.02f, scaleFactor / 1.05f); - } - } - - override def keyPressed(key:Int, c:Char) { - - // ESC - if(key == 1) quit = true - - if(c == '1') selectModel(nazcaMonkey) - if(c == '2') selectModel(bird) - if(c == '3') selectModel(strange) - if(c == '4') selectModel(snake) - if(c == '5') selectModel(star) - if(c == '6') selectModel(i18) - if(c == '7') selectModel(nazcaHeron) - if(c == '8') selectModel(tank) - if(c == '9') selectModel(dude) - if(c == '0') selectModel(basic) - - if(c == 'd') drawSegs = !drawSegs - if(c == 'm') drawCDTMesh = !drawCDTMesh - if(c == 't') drawMap = !drawMap - - if(c == 's') {algo = Seidel; selectModel(currentModel) } - if(c == 'c') {algo = CDT; selectModel(currentModel) } - if(c == 'e') {algo = EarClip; selectModel(currentModel) } - - // Experimental... - if(c == 'r') slCDT.refine - - } - - def selectModel(model: String) { - model match { - case "../data/nazca_monkey.dat" => - val clearPoint = Point(418, 282) - loadModel(nazcaMonkey, 4.5f, Point(400, 300), 1500, clearPoint) - case "../data/bird.dat" => - val clearPoint = Point(400, 300) - loadModel(bird, 25f, Point(400, 300), 350, clearPoint) - case "../data/i.snake" => - val clearPoint = Point(336f, 196f) - loadModel(snake, 10f, Point(600, 300), 10, clearPoint) - case "../data/star.dat" => - val clearPoint = Point(400, 204) - loadModel(star, -1f, Point(0f, 0f), 10, clearPoint) - case "../data/strange.dat" => - val clearPoint = Point(400, 268) - loadModel(strange, -1f, Point(0f, 0f), 15, clearPoint) - case "../data/i.18" => - val clearPoint = Point(510, 385) - loadModel(i18, 20f, Point(600f, 500f), 20, clearPoint) - case "../data/nazca_heron_old.dat" => - val clearPoint = Point(85, 290) - loadModel(nazcaHeron, 4.2f, Point(400f, 300f), 1500, clearPoint) - case "../data/tank.dat" => - val clearPoint = Point(450, 350) - loadModel(tank, -1f, Point(100f, 0f), 10, clearPoint) - case "../data/dude.dat" => - val clearPoint = Point(365, 427) - loadModel(dude, -1f, Point(100f, -200f), 10, clearPoint) - case "../data/basic.dat" => - val clearPoint = Point(500, 450) - loadModel(basic, -5f, Point(500, 450), 10, clearPoint) - case _ => - } - currentModel = model - } - - def loadModel(model: String, scale: Float, center: Point, maxTriangles: Int, clearPoint: Point) { - - println - println("************** " + model + " **************") - - val polyX = new ArrayBuffer[Float] - val polyY = new ArrayBuffer[Float] - var points = new ArrayBuffer[Point] - - val angle = Math.Pi - for (line <- Source.fromFile(model).getLines) { - val s = line.replaceAll("\n", "") - val tokens = s.split("[ ]+") - if(tokens.size == 2) { - var x = tokens(0).toFloat - var y = tokens(1).toFloat - // Transform the shape - polyX += (Math.cos(angle)*x - Math.sin(angle)*y).toFloat * scale + center.x - polyY += (Math.sin(angle)*x + Math.cos(angle)*y).toFloat * scale + center.y - points += new Point(polyX.last, polyY.last) - } else { - throw new Exception("Bad input file") - } - } - - segments = new ArrayBuffer[Segment] - for(i <- 0 until points.size-1) - segments += new Segment(points(i), points(i+1)) - segments += new Segment(points.first, points.last) - - println("Number of points = " + polyX.size) - println - - algo match { - - case Algo.CDT => { - - val pts = points.toArray - - val t1 = System.nanoTime - slCDT = new CDT(pts, clearPoint) - - // Add some holes.... - if(model == "../data/dude.dat") { - - val headHole = Array(Point(325f,437f), Point(320f,423f), Point(329f,413f), Point(332f,423f)) - val chestHole = Array(Point(320.72342f,480f), Point(338.90617f,465.96863f), - Point(347.99754f,480.61584f), Point(329.8148f,510.41534f), - Point(339.91632f,480.11077f), Point(334.86556f,478.09046f)) - - // Tramsform the points - for(i <- 0 until headHole.size) { - val hx = -headHole(i).x*scale + center.x - val hy = -headHole(i).y*scale + center.y - headHole(i) = Point(hx, hy) - } - for(i <- 0 until chestHole.size) { - val cx = -chestHole(i).x*scale + center.x - val cy = -chestHole(i).y*scale + center.y - chestHole(i) = Point(cx, cy) - } - - chestSegs = new ArrayBuffer[Segment] - for(i <- 0 until chestHole.size-1) - chestSegs += new Segment(chestHole(i), chestHole(i+1)) - chestSegs += new Segment(chestHole.first, chestHole.last) - - headSegs = new ArrayBuffer[Segment] - for(i <- 0 until headHole.size-1) - headSegs += new Segment(headHole(i), headHole(i+1)) - headSegs += new Segment(headHole.first, headHole.last) - - // Add the holes - slCDT.addHole(headHole) - slCDT.addHole(chestHole) - } - - slCDT triangulate - val runTime = System.nanoTime - t1 - - println("CDT average (ms) = " + runTime*1e-6) - println("Number of triangles = " + slCDT.triangles.size) - println - } - - case Algo.Seidel => { - - // Sediel triangulation - val t1 = System.nanoTime - seidel = new Triangulator(points) - val runTime = System.nanoTime - t1 - - println("Seidel average (ms) = " + runTime*1e-6) - println("Number of triangles = " + seidel.polygons.size) - - } - - case Algo.EarClip => { - - // Earclip - - earClipResults = new Array[poly2tri.earClip.Triangle](maxTriangles) - - for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle - - var xVerts = polyX.toArray - var yVerts = polyY.toArray - - val xv = if(currentModel != "../data/strange.dat") xVerts.reverse.toArray else xVerts - val yv = if(currentModel != "../data/strange.dat") yVerts.reverse.toArray else yVerts - - val t1 = System.nanoTime - earClip.triangulatePolygon(xv, yv, xVerts.size, earClipResults) - val runTime = System.nanoTime - t1 - - println - println("Earclip average (ms) = " + runTime*1e-6) - println("Number of triangles = " + earClip.numTriangles) - } - - case _ => - } - } -} diff --git a/scala/src/org/poly2tri/cdt/AFront.scala b/scala/src/org/poly2tri/cdt/AFront.scala deleted file mode 100644 index 0accfc6..0000000 --- a/scala/src/org/poly2tri/cdt/AFront.scala +++ /dev/null @@ -1,165 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.cdt - -import scala.collection.mutable.ArrayBuffer - -import shapes.{Point, Triangle, Segment} - -// Advancing front -class AFront(iTriangle: Triangle) { - - // Doubly linked list - var head = new Node(iTriangle.points(1), iTriangle) - val middle = new Node(iTriangle.points(0), iTriangle) - var tail = new Node(iTriangle.points(2), null) - - head.next = middle - middle.next = tail - middle.prev = head - tail.prev = middle - - // TODO: Use Red-Black Tree or Interval Tree for better search performance! - def locate(point: Point): Node = { - var node = head - while(node != tail) { - if(point.x >= node.point.x && point.x < node.next.point.x) - return node - node = node.next - } - null - } - - // Locate node containing given point - def locatePoint(point: Point): Node = { - var node = head - while(node != null) { - if(point == node.point) - return node - node = node.next - } - null - } - - def insert(point: Point, triangle: Triangle, nNode: Node) = { - val node = new Node(point, triangle) - nNode.triangle = triangle - nNode.next.prev = node - node.next = nNode.next - node.prev = nNode - nNode.next = node - node - } - - def insertLegalized(point: Point, triangle: Triangle, nNode: Node) = { - val node = new Node(triangle.points(1), triangle) - val rNode = nNode.next - rNode.prev = node - node.next = rNode - nNode.next = node - node.prev = nNode - node - } - - // Update advancing front with constrained edge triangles - def constrainedEdge(sNode: Node, eNode: Node, T1: ArrayBuffer[Triangle], - T2: ArrayBuffer[Triangle], edge: Segment) { - - var node = sNode.prev - - val point1 = edge.q - val point2 = edge.p - - // Scan the advancing front and update Node triangle pointers - // TODO: Make this more efficient - while(node != null && node != eNode.next) { - T2.foreach(t => { - if(t.contains(node.point, node.next.point)) - node.triangle = t - }) - T1.foreach(t => { - if(t.contains(node.point, node.next.point)) - node.triangle = t - }) - node = node.next - } - - } - - // Transition from AFront traversal to interior mesh traversal - def aboveEdge(first: Node, pNode: Node, last: Triangle, - point2: Point, ahead:Boolean): Node = - if(ahead) { - val n = new Node(point2, pNode.prev.triangle) - link (first, n, last) - n.next = pNode - pNode.prev = n - n - } else { - val n = new Node(point2, last) - link (n, first, last) - pNode.next = n - n.prev = pNode - pNode - } - - def -=(tuple: Tuple3[Node, Node, Triangle]) { - val (node, kNode, triangle) = tuple - kNode.next.prev = node - node.next = kNode.next - node.triangle = triangle - } - - def link(node1: Node, node2: Node, t: Triangle) { - node1.next = node2 - node2.prev = node1 - node1.triangle = t - } - - // NOT IMPLEMENTED - def basin(node: Node) { - if(node.next != tail) { - val p1 = node.point - val p2 = node.next.point - val slope = (p1.y - p2.y) / (p1.x - p2.x) - if(slope < Math.Pi*3/4) - println("basin slope = " + slope) - } - - } - -} - -// Advancing front node -class Node(val point: Point, var triangle: Triangle) { - var next: Node = null - var prev: Node = null -} \ No newline at end of file diff --git a/scala/src/org/poly2tri/cdt/CDT.scala b/scala/src/org/poly2tri/cdt/CDT.scala deleted file mode 100644 index fef50d8..0000000 --- a/scala/src/org/poly2tri/cdt/CDT.scala +++ /dev/null @@ -1,549 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.cdt - -import scala.collection.mutable.ArrayBuffer - -import shapes.{Segment, Point, Triangle} -import utils.Util - -/** - * Sweep-line, Constrained Delauney Triangulation (CDT) - * See: Domiter, V. and Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation', - * International Journal of Geographical Information Science - */ - -// clearPoint is any interior point inside the polygon -class CDT(polyLine: Array[Point], clearPoint: Point) { - - // Triangle list - def triangles = mesh.triangles - def triangleMesh = mesh.map - def debugTriangles = mesh.debug - - val cList = new ArrayBuffer[Point] - - var refined = false - - // Initialize edges - initEdges(polyLine) - - // Add a hole - def addHole(holePolyLine: Array[Point]) { - initEdges(holePolyLine) - points = points ++ holePolyLine.toList - } - - // Add an internal point - // Good for manually refining the mesh - def addPoint(point: Point) { - points = point :: points - } - - // Triangulate simple polygon with holes - def triangulate { - - mesh.map.clear - mesh.triangles.clear - mesh.debug.clear - - var xmax, xmin = points.first.x - var ymax, ymin = points.first.y - - // Calculate bounds - for(i <- 0 until points.size) { - val p = points(i) - if(p.x > xmax) xmax = p.x - if(p.x < xmin) xmin = p.x - if(p.y > ymax) ymax = p.y - if(p.y < ymin) ymin = p.y - } - - val deltaX = ALPHA * (xmax - xmin) - val deltaY = ALPHA * (ymax - ymin) - val p1 = Point(xmin - deltaX, ymin - deltaY) - val p2 = Point(xmax + deltaX, p1.y) - - // Sort the points along y-axis - points = pointSort - - // Initial triangle - val iTriangle = new Triangle(Array(points(0), p1, p2)) - mesh.map += iTriangle - aFront = new AFront(iTriangle) - - // Sweep points; build mesh - sweep - // Finalize triangulation - finalization - - } - - // Create edges and connect end points; update edge event pointer - private def initEdges(pts: Array[Point]) { - // Connect pts - for(i <- 0 until pts.size-1) { - val endPoints = validatePoints(pts(i), pts(i+1)) - val edge = new Segment(endPoints(0), endPoints(1)) - endPoints(1).edges += edge - } - // Connect endpoints - val endPoints = validatePoints(pts.first, pts.last) - val edge = new Segment(endPoints(0), endPoints(1)) - endPoints(1).edges += edge - } - - private def validatePoints(p1: Point, p2: Point): List[Point] = { - if(p1.y > p2.y) { - // For CDT we want q to be the point with > y - return List(p2, p1) - } else if(p1.y == p2.y) { - // If y values are equal, make sure point with smaller x value - // is to the left - if(p1.x > p2.x) { - return List(p2, p1) - } else if(p1.x == p2.x) { - throw new Exception("Duplicate point") - } - } - List(p1, p2) - } - - // Merge sort: O(n log n) - private def pointSort: List[Point] = - Util.msort((p1: Point, p2: Point) => p1 > p2)(points) - - // Implement sweep-line - private def sweep { - val size = if(refined) 1 else points.size - for(i <- 1 until points.size) { - val point = points(i) - // Process Point event - val node = pointEvent(point) - // Process edge events - point.edges.foreach(e => edgeEvent(e, node)) - } - } - - // Final step in the sweep-line CDT - // Clean exterior triangles - private def finalization { - var found = false - mesh.map.foreach(m => { - if(!found) - // Mark the originating clean triangle - if(m.pointIn(clearPoint)) { - found = true - cleanTri = m - } - m.markNeighborEdges - }) - // Collect interior triangles constrained by edges - mesh clean cleanTri - } - - // Delauney Refinement: Refine triangules using Steiner points - // Probably overkill for 2D games, and will create a large number of - // triangles that are probably unoptimal for a physics engine like - // Box2D.... Better to manually enter interior points for mesh "smoothing" - // TODO: Finish implementation... Maybe! - def refine { - cList.clear - mesh.triangles.foreach(t => { - if(t.thin) { - val center = Util.circumcenter(t.points(0), t.points(1), t.points(2)) - cList += center - addPoint(center) - } - }) - // Retriangulate - if(cList.size > 0) - triangulate - } - - // Point event - private def pointEvent(point: Point): Node = { - - val node = aFront.locate(point) - - // Projected point hits advancing front; create new triangle - val pts = Array(point, node.point, node.next.point) - val triangle = new Triangle(pts) - - mesh.map += triangle - - // Legalize - val newNode = legalization(triangle, node) - // Fill in adjacent triangles if required - scanAFront(newNode) - newNode - - } - - // EdgeEvent - private def edgeEvent(edge: Segment, node: Node) { - - // Locate the first intersected triangle - val firstTriangle = if(!node.triangle.contains(edge.q)) - node.triangle - else - node.triangle.locateFirst(edge) - - if(firstTriangle != null && !firstTriangle.contains(edge)) { - - // Interior mesh traversal - edge is "burried" in the mesh - // Constrained edge lies below the advancing front. Traverse through intersected triangles, - // form empty pseudo-polygons, and re-triangulate - - // Collect intersected triangles - val tList = new ArrayBuffer[Triangle] - tList += firstTriangle - - while(tList.last != null && !tList.last.contains(edge.p)) - tList += tList.last.findNeighbor(edge.p) - - // TODO: Finish implementing edge insertion which combines advancing front (AF) - // and triangle traversal respectively. See figure 14(a) from Domiter et al. - // Should only occur with complex patterns of interior points - // Already added provision for transitioning from AFront traversal to - // interior mesh traversal - may need to add the opposite case - if(tList.last == null) - throw new Exception("Not implemented yet - interior points too complex") - - // Neighbor triangles - // HashMap or set may improve performance - val nTriangles = new ArrayBuffer[Triangle] - - // Remove old triangles; collect neighbor triangles - // Keep duplicates out - tList.foreach(t => { - t.neighbors.foreach(n => if(n != null && !tList.contains(n)) nTriangles += n) - mesh.map -= t - }) - - // Using a hashMap or set may improve performance - val lPoints = new ArrayBuffer[Point] - val rPoints = new ArrayBuffer[Point] - - // Collect points left and right of edge - tList.foreach(t => { - t.points.foreach(p => { - if(p != edge.q && p != edge.p) { - if(Util.orient2d(edge.q, edge.p, p) > 0 ) { - // Keep duplicate points out - if(!lPoints.contains(p)) { - lPoints += p - } - } else { - // Keep duplicate points out - if(!rPoints.contains(p)) - rPoints += p - } - } - }) - }) - - // Triangulate empty areas. - val T1 = new ArrayBuffer[Triangle] - triangulate(lPoints.toArray, List(edge.q, edge.p), T1) - val T2 = new ArrayBuffer[Triangle] - triangulate(rPoints.toArray, List(edge.q, edge.p), T2) - - // Update neighbors - edgeNeighbors(nTriangles, T1) - edgeNeighbors(nTriangles, T2) - T1.last.markNeighbor(T2.last) - - // Update advancing front - - val ahead = (edge.p.x > edge.q.x) - val point1 = if(ahead) edge.q else edge.p - val point2 = if(ahead) edge.p else edge.q - - val sNode = if(ahead) node else aFront.locate(point1) - val eNode = aFront.locate(point2) - - aFront.constrainedEdge(sNode, eNode, T1, T2, edge) - - // Mark constrained edge - T1.last markEdge(point1, point2) - T2.last markEdge(point1, point2) - // Copy constraied edges from old triangles - T1.foreach(t => t.markEdge(tList)) - T2.foreach(t => t.markEdge(tList)) - - } else if(firstTriangle == null) { - - // AFront traversal - // No triangles are intersected by the edge; edge must lie outside the mesh - // Apply constraint; traverse the advancing front, and build triangles - - var pNode, first = node - val points = new ArrayBuffer[Point] - - // Neighbor triangles - val nTriangles = new ArrayBuffer[Triangle] - nTriangles += pNode.triangle - - val ahead = (edge.p.x > edge.q.x) - - // If this is true we transition from AFront traversal to - // interior mesh traversal - var aboveEdge = false - - if(ahead) { - // Scan right - pNode = pNode.next - while(pNode.point != edge.p && !aboveEdge) { - points += pNode.point - nTriangles += pNode.triangle - pNode = pNode.next - aboveEdge = edge < pNode.point - } - } else { - // Scan left - pNode = pNode.prev - while(pNode.point != edge.p && !aboveEdge) { - points += pNode.point - nTriangles += pNode.triangle - pNode = pNode.prev - aboveEdge = edge < pNode.point - } - nTriangles += pNode.triangle - } - - val point2 = if(aboveEdge) { - val p1 = pNode.point - val p2 = if(ahead) pNode.prev.point else pNode.next.point - edge.intersect(p1, p2) - } else { - edge.p - } - - // Triangulate empty areas. - val T = new ArrayBuffer[Triangle] - triangulate(points.toArray, List(edge.q, point2), T) - - // Update neighbors - edgeNeighbors(nTriangles, T) - - // Mark constrained edge - T.last markEdge(edge.q, point2) - - // Update advancing front - if(aboveEdge) { - val iNode = aFront.aboveEdge(first, pNode, T.last, point2, ahead) - edgeEvent(new Segment(edge.p, point2), iNode) - } else { - if(ahead) - aFront link (first, pNode, T.last) - else - aFront link (pNode, first, T.last) - } - - } else if(firstTriangle.contains(edge.q, edge.p)) { - // Constrained edge lies on the side of a triangle - // Mark constrained edge - firstTriangle markEdge(edge.q, edge.p) - firstTriangle.finalized = true - } else { - throw new Exception("Triangulation error - unexpected case") - } - - } - - // Update neigbor pointers for edge event - // Inneficient, but it works well... - private def edgeNeighbors(nTriangles: ArrayBuffer[Triangle], T: ArrayBuffer[Triangle]) { - - for(t1 <- nTriangles) - for(t2 <- T) - t2.markNeighbor(t1) - - for(i <- 0 until T.size) - for(j <- i+1 until T.size) - T(i).markNeighbor(T(j)) - - } - - // Marc Vigo Anglada's triangulate pseudo-polygon algo - // See "An improved incremental algorithm for constructing restricted Delaunay triangulations" - private def triangulate(P: Array[Point], ab: List[Point], T: ArrayBuffer[Triangle]) { - - val a = ab(0) - val b = ab(1) - var i = 0 - - if(P.size > 1) { - var c = P(0) - for(j <- 1 until P.size) { - if(illegal(a, b, c, P(j))) { - c = P(j) - i = j - } - } - val PE = P.slice(0, i) - val PD = P.slice(i+1, P.size) - triangulate(PE, List(a, c), T) - triangulate(PD, List(c, b), T) - } - - if(!P.isEmpty) { - val ccw = Util.orient2d(a, P(i), b) > 0 - val points = if(ccw) Array(a, P(i), b) else Array(a, b, P(i)) - T += new Triangle(points) - T.last.finalized = true - mesh.map += T.last - } - - } - - // Scan left and right along AFront to fill holes - private def scanAFront(n: Node) = { - - var node1 = n.next - // Update right - if(node1.next != null) { - var angle = 0.0 - do { - angle = fill(node1) - node1 = node1.next - } while(angle <= PI_2 && angle >= -PI_2 && node1.next != null) - } - - var node2 = n.prev - // Update left - if(node2.prev != null) { - var angle = 0.0 - do { - angle = fill(node2) - node2 = node2.prev - } while(angle <= PI_2 && angle >= -PI_2 && node2.prev != null) - } - - } - - // Fill empty space with a triangle - private def fill(node: Node): Double = { - - val a = (node.prev.point - node.point) - val b = (node.next.point - node.point) - val angle = Math.atan2(a cross b, a dot b) - // Is the angle acute? - if(angle <= PI_2 && angle >= -PI_2) { - val points = Array(node.prev.point, node.point, node.next.point) - val triangle = new Triangle(points) - // Update neighbor pointers - node.prev.triangle.markNeighbor(triangle) - node.triangle.markNeighbor(triangle) - mesh.map += triangle - aFront -= (node.prev, node, triangle) - } - angle - } - - // Circumcircle test. - // Determines if point d lies inside triangle abc's circumcircle - private def illegal(a: Point, b: Point, c: Point, d: Point): Boolean = { - val ccw = Util.orient2d(a, b, c) > 0 - // Make sure abc is oriented counter-clockwise - if(ccw) - Util.incircle(a, b, c, d) - else - Util.incircle(a, c, b, d) - } - - // Ensure adjacent triangles are legal - // If illegal, flip edges and update triangle's pointers - private def legalization(t1: Triangle, node: Node): Node = { - - val t2 = node.triangle - - val point = t1.points(0) - val oPoint = t2 oppositePoint t1 - - // Pints are oriented ccw - val illegal = Util.incircle(t1.points(1), t1.points(2), t1.points(0), oPoint) - - if(illegal && !t2.finalized) { - - // Flip edge and rotate everything clockwise - - // Legalize points - t1.legalize(oPoint) - t2.legalize(oPoint, point) - - // Update neighbors - - // Copy old neighbors - val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2)) - // Clear old neighbors - t2.clearNeighbors - // Update new neighbors - for(n <- neighbors) { - if(n != null) { - t1.markNeighbor(n) - t2.markNeighbor(n) - } - } - t2.markNeighbor(t1) - - // Don't legalize these triangles again - t2.finalized = true - t1.finalized = true - - // Update advancing front - aFront.insertLegalized(t1.points(1), t1, node) - - } else { - - // Update neighbor - t2.markNeighbor(t1) - // Update advancing front - aFront.insert(point, t1, node) - - } - } - - // The triangle mesh - private val mesh = new Mesh - // Advancing front - private var aFront: AFront = null - // Sorted point list - private var points = polyLine.toList - // Half Pi - private val PI_2 = Math.Pi/2 - // Inital triangle factor - private val ALPHA = 0.3f - // Triangle used to clean interior - private var cleanTri: Triangle = null - -} diff --git a/scala/src/org/poly2tri/cdt/Mesh.scala b/scala/src/org/poly2tri/cdt/Mesh.scala deleted file mode 100644 index fdd2a8a..0000000 --- a/scala/src/org/poly2tri/cdt/Mesh.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.cdt - -import scala.collection.mutable.ArrayBuffer - -import shapes.{Point, Triangle} - -class Mesh { - - // Triangles that constitute the mesh - val map = new ArrayBuffer[Triangle] - // Debug triangles - val debug = new ArrayBuffer[Triangle] - val triangles = new ArrayBuffer[Triangle] - - // Recursively collect interior triangles and clean the mesh - // Excludes exterior triangles outside constrained edges - // TODO: Investigate depth first search as an alternative - def clean(triangle: Triangle) { - - if(triangle != null && !triangle.interior) { - triangle.interior = true - triangles += triangle - for(i <- 0 until 3) { - if(!triangle.edges(i)) - clean(triangle.neighbors(i)) - } - } - } - -} diff --git a/scala/src/org/poly2tri/earClip/EarClip.scala b/scala/src/org/poly2tri/earClip/EarClip.scala deleted file mode 100644 index 431ac65..0000000 --- a/scala/src/org/poly2tri/earClip/EarClip.scala +++ /dev/null @@ -1,373 +0,0 @@ -/** - * Ported from jBox2D. Original author: ewjordan - * Triangulates a polygon using simple ear-clipping algorithm. Returns - * size of Triangle array unless the polygon can't be triangulated. - * This should only happen if the polygon self-intersects, - * though it will not _always_ return null for a bad polygon - it is the - * caller's responsibility to check for self-intersection, and if it - * doesn't, it should at least check that the return value is non-null - * before using. You're warned! - * - * Triangles may be degenerate, especially if you have identical points - * in the input to the algorithm. Check this before you use them. - * - * This is totally unoptimized, so for large polygons it should not be part - * of the simulation loop. - * - * Returns: - * -1 if algorithm fails (self-intersection most likely) - * 0 if there are not enough vertices to triangulate anything. - * Number of triangles if triangulation was successful. - * - * results will be filled with results - ear clipping always creates vNum - 2 - * or fewer (due to pinch point polygon snipping), so allocate an array of - * this size. - */ -package org.poly2tri.earClip - -import shapes.Point -import utils.Util - -class EarClip { - - val tol = .001f - var hasPinchPoint = false - var pinchIndexA = -1 - var pinchIndexB = -1 - var pin: Poly = null - - var numTriangles = 0 - - def triangulatePolygon(xv: Array[Float], yv: Array[Float], vn: Int, results: Array[Triangle]): Int = { - - if (vn < 3) return 0 - var vNum = vn - - //Recurse and split on pinch points - val pA = new Poly - val pB = new Poly - pin = new Poly(xv, yv, vNum) - if (resolvePinchPoint(pin,pA,pB)){ - val mergeA = new Array[Triangle](pA.nVertices) - val mergeB = new Array[Triangle](pB.nVertices) - for (i <- 0 until pA.nVertices) { - mergeA(i) = new Triangle(); - } - for (i <- 0 until pB.nVertices) { - mergeB(i) = new Triangle(); - } - val nA = triangulatePolygon(pA.x,pA.y,pA.nVertices,mergeA) - val nB = triangulatePolygon(pB.x,pB.y,pB.nVertices,mergeB) - if (nA == -1 || nB == -1){ - numTriangles = -1 - return numTriangles - } - for (i <- 0 until nA){ - results(i).set(mergeA(i)); - } - for (i <- 0 until nB){ - results(nA+i).set(mergeB(i)); - } - numTriangles = (nA+nB) - return numTriangles - } - - val buffer = new Array[Triangle](vNum-2); - for (i <- 0 until buffer.size) { - buffer(i) = new Triangle(); - } - var bufferSize = 0; - var xrem = new Array[Float](vNum) - var yrem = new Array[Float](vNum) - for (i <- 0 until vNum) { - xrem(i) = xv(i); - yrem(i) = yv(i); - } - - val xremLength = vNum; - - while (vNum > 3) { - //System.out.println("vNum: "+vNum); - // Find an ear - var earIndex = -1; - var earMaxMinCross = -1000.0f; - for (i <- 0 until vNum) { - if (isEar(i, xrem, yrem, vNum)) { - val lower = remainder(i-1,vNum); - val upper = remainder(i+1,vNum); - var d1 = Point(xrem(upper)-xrem(i),yrem(upper)-yrem(i)); - var d2 = Point(xrem(i)-xrem(lower),yrem(i)-yrem(lower)); - var d3 = Point(xrem(lower)-xrem(upper),yrem(lower)-yrem(upper)); - - d1 = d1.normalize - d2 = d2.normalize - d3 = d3.normalize - val cross12 = Math.abs( d1 cross d2 ) - val cross23 = Math.abs( d2 cross d3 ) - val cross31 = Math.abs( d3 cross d1 ) - //Find the maximum minimum angle - val minCross = Math.min(cross12, Math.min(cross23,cross31)) - if (minCross > earMaxMinCross){ - earIndex = i - earMaxMinCross = minCross - } - } - } - - // If we still haven't found an ear, we're screwed. - // Note: sometimes this is happening because the - // remaining points are collinear. Really these - // should just be thrown out without halting triangulation. - if (earIndex == -1){ - - System.out.println("Couldn't find an ear, dumping remaining poly:\n"); - System.out.println("Please submit this dump to ewjordan at Box2d forums\n"); - - assert(false) - - for (i <- 0 until bufferSize) { - results(i).set(buffer(i)); - } - - if (bufferSize > 0) return bufferSize; - else { - numTriangles = -1 - return numTriangles - } - } - - // Clip off the ear: - // - remove the ear tip from the list - - vNum -= 1; - val newx = new Array[Float](vNum) - val newy = new Array[Float](vNum) - var currDest = 0; - for (i <- 0 until vNum) { - if (currDest == earIndex) currDest += 1 - newx(i) = xrem(currDest); - newy(i) = yrem(currDest); - currDest += 1; - } - - // - add the clipped triangle to the triangle list - val under = if(earIndex == 0) (vNum) else (earIndex - 1) - val over = if(earIndex == vNum) 0 else (earIndex + 1) - val toAdd = new Triangle(xrem(earIndex), yrem(earIndex), xrem(over), yrem(over), xrem(under), yrem(under)); - buffer(bufferSize) = toAdd - bufferSize += 1; - - // - replace the old list with the new one - xrem = newx; - yrem = newy; - } - - val toAdd = new Triangle(xrem(1), yrem(1), xrem(2), yrem(2), xrem(0), yrem(0)) - buffer(bufferSize) = toAdd; - bufferSize += 1; - - assert(bufferSize == xremLength-2) - - for (i <- 0 until bufferSize) { - results(i).set(buffer(i)) - } - numTriangles = bufferSize - return numTriangles - } - - /** - * Finds and fixes "pinch points," points where two polygon - * vertices are at the same point. - * - * If a pinch point is found, pin is broken up into poutA and poutB - * and true is returned; otherwise, returns false. - * - * Mostly for internal use. - * - * O(N^2) time, which sucks... - */ - private def resolvePinchPoint(pin: Poly, poutA: Poly, poutB: Poly): Boolean = { - - if (pin.nVertices < 3) return false - hasPinchPoint = false - pinchIndexA = -1 - pinchIndexB = -1 - pinchIndex - if (hasPinchPoint){ - val sizeA = pinchIndexB - pinchIndexA; - if (sizeA == pin.nVertices) return false; - val xA = new Array[Float](sizeA); - val yA = new Array[Float](sizeA); - for (i <- 0 until sizeA){ - val ind = remainder(pinchIndexA+i,pin.nVertices); - xA(i) = pin.x(ind); - yA(i) = pin.y(ind); - } - val tempA = new Poly(xA,yA,sizeA); - poutA.set(tempA); - - val sizeB = pin.nVertices - sizeA; - val xB = new Array[Float](sizeB); - val yB = new Array[Float](sizeB); - for (i <- 0 until sizeB){ - val ind = remainder(pinchIndexB+i,pin.nVertices); - xB(i) = pin.x(ind); - yB(i) = pin.y(ind); - } - val tempB = new Poly(xB,yB,sizeB); - poutB.set(tempB); - } - return hasPinchPoint; - } - - //Fix for obnoxious behavior for the % operator for negative numbers... - private def remainder(x: Int, modulus: Int): Int = { - var rem = x % modulus - while (rem < 0){ - rem += modulus - } - return rem - } - - def pinchIndex: Boolean = { - for (i <- 0 until pin.nVertices) { - if(!hasPinchPoint) { - for (j <- i+1 until pin.nVertices){ - //Don't worry about pinch points where the points - //are actually just dupe neighbors - if (Math.abs(pin.x(i)-pin.x(j))= xvLength || i < 0 || xvLength < 3) { - return false; - } - var upper = i + 1 - var lower = i - 1 - if (i == 0) { - dx0 = xv(0) - xv(xvLength - 1) - dy0 = yv(0) - yv(xvLength - 1) - dx1 = xv(1) - xv(0) - dy1 = yv(1) - yv(0) - lower = xvLength - 1 - } - else if (i == xvLength - 1) { - dx0 = xv(i) - xv(i - 1); - dy0 = yv(i) - yv(i - 1); - dx1 = xv(0) - xv(i); - dy1 = yv(0) - yv(i); - upper = 0; - } - else { - dx0 = xv(i) - xv(i - 1); - dy0 = yv(i) - yv(i - 1); - dx1 = xv(i + 1) - xv(i); - dy1 = yv(i + 1) - yv(i); - } - val cross = dx0 * dy1 - dx1 * dy0; - if (cross > 0) - return false; - val myTri = new Triangle(xv(i), yv(i), xv(upper), yv(upper), xv(lower), yv(lower)) - for (j <- 0 until xvLength) { - if (!(j == i || j == lower || j == upper)) { - if (myTri.containsPoint(xv(j), yv(j))) - return false; - } - } - return true; - } - -} - -class Poly(var x: Array[Float], var y: Array[Float], var nVertices: Int) { - - var areaIsSet = false - var area = 0f - - def this(_x: Array[Float], _y: Array[Float]) = this(_x,_y,_x.size) - def this() = this(null, null, 0) - - def set(p: Poly ) { - if (nVertices != p.nVertices){ - nVertices = p.nVertices; - x = new Array[Float](nVertices) - y = new Array[Float](nVertices) - } - - for (i <- 0 until nVertices) { - x(i) = p.x(i) - y(i) = p.y(i) - } - areaIsSet = false - } -} - -class Triangle(var x1: Float, var y1: Float, var x2: Float, var y2: Float, var x3: Float, var y3: Float) { - - def this() = this(0,0,0,0,0,0) - - val x = new Array[Float](3) - val y = new Array[Float](3) - - // Automatically fixes orientation to ccw - - val dx1 = x2-x1 - val dx2 = x3-x1 - val dy1 = y2-y1 - val dy2 = y3-y1 - val cross = dx1*dy2-dx2*dy1 - val ccw = (cross>0) - if (ccw){ - x(0) = x1; x(1) = x2; x(2) = x3; - y(0) = y1; y(1) = y2; y(2) = y3; - } else{ - x(0) = x1; x(1) = x3; x(2) = x2; - y(0) = y1; y(1) = y3; y(2) = y2; - } - - def set(t: Triangle) { - x(0) = t.x(0) - x(1) = t.x(1) - x(2) = t.x(2) - y(0) = t.y(0) - y(1) = t.y(1) - y(2) = t.y(2) - } - - - def containsPoint(_x: Float, _y: Float): Boolean = { - - val vx2 = _x-x(0); val vy2 = _y-y(0); - val vx1 = x(1)-x(0); val vy1 = y(1)-y(0); - val vx0 = x(2)-x(0); val vy0 = y(2)-y(0); - - val dot00 = vx0*vx0+vy0*vy0; - val dot01 = vx0*vx1+vy0*vy1; - val dot02 = vx0*vx2+vy0*vy2; - val dot11 = vx1*vx1+vy1*vy1; - val dot12 = vx1*vx2+vy1*vy2; - val invDenom = 1.0f / (dot00*dot11 - dot01*dot01); - val u = (dot11*dot02 - dot01*dot12)*invDenom; - val v = (dot00*dot12 - dot01*dot02)*invDenom; - - return ((u>=0)&&(v>=0)&&(u+v<=1)); - } - - } \ No newline at end of file diff --git a/scala/src/org/poly2tri/seidel/MonotoneMountain.scala b/scala/src/org/poly2tri/seidel/MonotoneMountain.scala deleted file mode 100644 index 7b587ea..0000000 --- a/scala/src/org/poly2tri/seidel/MonotoneMountain.scala +++ /dev/null @@ -1,165 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import scala.collection.mutable.{ArrayBuffer, Queue} - -import shapes.Point - -// Doubly linked list -class MonotoneMountain { - - var tail, head: Point = null - var size = 0 - - private val convexPoints = new ArrayBuffer[Point] - // Monotone mountain points - val monoPoly = new ArrayBuffer[Point] - // Triangles that constitute the mountain - val triangles = new ArrayBuffer[Array[Point]] - // Convex polygons that constitute the mountain - val convexPolies = new ArrayBuffer[Array[Point]] - // Used to track which side of the line we are on - private var positive = false - // Almost Pi! - private val PI_SLOP = 3.1 - - // Append a point to the list - def +=(point: Point) { - size match { - case 0 => - head = point - size += 1 - case 1 => - // Keep repeat points out of the list - if(point ! head) { - tail = point - tail.prev = head - head.next = tail - size += 1 - } - case _ => - // Keep repeat points out of the list - if(point ! tail) { - tail.next = point - point.prev = tail - tail = point - size += 1 - } - } - } - - // Remove a point from the list - def remove(point: Point) { - val next = point.next - val prev = point.prev - point.prev.next = next - point.next.prev = prev - size -= 1 - } - - // Partition a x-monotone mountain into triangles O(n) - // See "Computational Geometry in C", 2nd edition, by Joseph O'Rourke, page 52 - def process { - - // Establish the proper sign - positive = angleSign - // create monotone polygon - for dubug purposes - genMonoPoly - - // Initialize internal angles at each nonbase vertex - // Link strictly convex vertices into a list, ignore reflex vertices - var p = head.next - while(p != tail) { - val a = angle(p) - // If the point is almost colinear with it's neighbor, remove it! - if(a >= PI_SLOP || a <= -PI_SLOP || a == 0.0) - remove(p) - else if(convex(p)) - convexPoints += p - p = p.next - } - - triangulate - - } - - private def triangulate { - - while(!convexPoints.isEmpty) { - - val ear = convexPoints.remove(0) - val a = ear.prev - val b = ear - val c = ear.next - val triangle = Array(a, b, c) - - triangles += triangle - - // Remove ear, update angles and convex list - remove(ear) - if(valid(a)) convexPoints += a - if(valid(c)) convexPoints += c - } - assert(size <= 3, "Triangulation bug, please report") - - } - - private def valid(p: Point) = (p != head && p != tail && convex(p)) - - // Create the monotone polygon - private def genMonoPoly { - var p = head - while(p != null) { - monoPoly += p - p = p.next - } - } - - private def angle(p: Point) = { - val a = (p.next - p) - val b = (p.prev - p) - Math.atan2(a cross b, a dot b) - } - - private def angleSign = { - val a = (head.next - head) - val b = (tail - head) - (Math.atan2(a cross b, a dot b) >= 0) - } - - // Determines if the inslide angle is convex or reflex - private def convex(p: Point) = { - if(positive != (angle(p) >= 0)) false - else true - } - -} diff --git a/scala/src/org/poly2tri/seidel/Node.scala b/scala/src/org/poly2tri/seidel/Node.scala deleted file mode 100644 index ef47cd4..0000000 --- a/scala/src/org/poly2tri/seidel/Node.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import scala.collection.mutable.ArrayBuffer - -import shapes.Segment - -// Node for a Directed Acyclic graph (DAG) -abstract class Node(var left: Node, var right: Node) { - - if(left != null) left.parentList += this - if(right != null) right.parentList += this - - var parentList = new ArrayBuffer[Node] - - def locate(s: Segment): Sink - - // Replace a node in the graph with this node - // Make sure parent pointers are updated - def replace(node: Node) { - for(parent <- node.parentList) { - // Select the correct node to replace (left or right child) - if(parent.left == node) parent.left = this - else parent.right = this - parentList += parent - } - } -} diff --git a/scala/src/org/poly2tri/seidel/QueryGraph.scala b/scala/src/org/poly2tri/seidel/QueryGraph.scala deleted file mode 100644 index c9eb4ce..0000000 --- a/scala/src/org/poly2tri/seidel/QueryGraph.scala +++ /dev/null @@ -1,92 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import scala.collection.mutable.ArrayBuffer - -import shapes.{Segment, Trapezoid} - -// Directed Acyclic graph (DAG) -// See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 - -class QueryGraph(var head: Node) { - - def locate(s: Segment) = head.locate(s).trapezoid - - def followSegment(s: Segment) = { - - val trapezoids = new ArrayBuffer[Trapezoid] - trapezoids += locate(s) - var j = 0 - while(s.q.x > trapezoids(j).rightPoint.x) { - if(s > trapezoids(j).rightPoint) { - trapezoids += trapezoids(j).upperRight - } else { - trapezoids += trapezoids(j).lowerRight - } - j += 1 - } - trapezoids - } - - def replace(sink: Sink, node: Node) { - if(sink.parentList.size == 0) { - head = node - } else { - node replace sink - } - } - - def case1(sink: Sink, s: Segment, tList: Array[Trapezoid]) { - val yNode = new YNode(s, Sink.init(tList(1)), Sink.init(tList(2))) - val qNode = new XNode(s.q, yNode, Sink.init(tList(3))) - val pNode = new XNode(s.p, Sink.init(tList(0)), qNode) - replace(sink, pNode) - } - - def case2(sink: Sink, s: Segment, tList: Array[Trapezoid]) { - val yNode = new YNode(s, Sink.init(tList(1)), Sink.init(tList(2))) - val pNode = new XNode(s.p, Sink.init(tList(0)), yNode) - replace(sink, pNode) - } - - def case3(sink: Sink, s: Segment, tList: Array[Trapezoid]) { - val yNode = new YNode(s, Sink.init(tList(0)), Sink.init(tList(1))) - replace(sink, yNode) - } - - def case4(sink: Sink, s: Segment, tList: Array[Trapezoid]) { - val yNode = new YNode(s, Sink.init(tList(0)), Sink.init(tList(1))) - val qNode = new XNode(s.q, yNode, Sink.init(tList(2))) - replace(sink, qNode) - } - -} diff --git a/scala/src/org/poly2tri/seidel/Sink.scala b/scala/src/org/poly2tri/seidel/Sink.scala deleted file mode 100644 index c3c48a6..0000000 --- a/scala/src/org/poly2tri/seidel/Sink.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import shapes.{Segment, Trapezoid} - -object Sink { - - def init(trapezoid: Trapezoid) = { - if(trapezoid.sink != null) - trapezoid.sink - else - new Sink(trapezoid) - } -} - -class Sink(val trapezoid: Trapezoid) extends Node(null, null) { - - trapezoid.sink = this - override def locate(s: Segment): Sink = this - -} diff --git a/scala/src/org/poly2tri/seidel/TrapezoidalMap.scala b/scala/src/org/poly2tri/seidel/TrapezoidalMap.scala deleted file mode 100644 index b9e38fe..0000000 --- a/scala/src/org/poly2tri/seidel/TrapezoidalMap.scala +++ /dev/null @@ -1,187 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import scala.collection.mutable.{HashSet, ArrayBuffer} - -import shapes.{Point, Segment, Trapezoid} - -// See "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 - -class TrapezoidalMap { - - // Trapezoid container - val map = HashSet.empty[Trapezoid] - // AABB margin - var margin = 50f - - // Bottom segment that spans multiple trapezoids - private var bCross: Segment = null - // Top segment that spans multiple trapezoids - private var tCross: Segment = null - - def clear { - bCross = null - tCross = null - } - - // Case 1: segment completely enclosed by trapezoid - // break trapezoid into 4 smaller trapezoids - def case1(t: Trapezoid, s: Segment) = { - - val trapezoids = new Array[Trapezoid](4) - trapezoids(0) = new Trapezoid(t.leftPoint, s.p, t.top, t.bottom) - trapezoids(1) = new Trapezoid(s.p, s.q, t.top, s) - trapezoids(2) = new Trapezoid(s.p, s.q, s, t.bottom) - trapezoids(3) = new Trapezoid(s.q, t.rightPoint, t.top, t.bottom) - - trapezoids(0).updateLeft(t.upperLeft, t.lowerLeft) - trapezoids(1).updateLeftRight(trapezoids(0), null, trapezoids(3), null) - trapezoids(2).updateLeftRight(null, trapezoids(0), null, trapezoids(3)) - trapezoids(3).updateRight(t.upperRight, t.lowerRight) - - trapezoids - } - - // Case 2: Trapezoid contains point p, q lies outside - // break trapezoid into 3 smaller trapezoids - def case2(t: Trapezoid, s: Segment) = { - - val rp = if(s.q.x == t.rightPoint.x) s.q else t.rightPoint - - val trapezoids = new Array[Trapezoid](3) - trapezoids(0) = new Trapezoid(t.leftPoint, s.p, t.top, t.bottom) - trapezoids(1) = new Trapezoid(s.p, rp, t.top, s) - trapezoids(2) = new Trapezoid(s.p, rp, s, t.bottom) - - trapezoids(0).updateLeft(t.upperLeft, t.lowerLeft) - trapezoids(1).updateLeftRight(trapezoids(0), null, t.upperRight, null) - trapezoids(2).updateLeftRight(null, trapezoids(0), null, t.lowerRight) - - bCross = t.bottom - tCross = t.top - - s.above = trapezoids(1) - s.below = trapezoids(2) - - trapezoids - } - - // Case 3: Trapezoid is bisected - def case3(t: Trapezoid, s: Segment) = { - - val lp = if(s.p.x == t.leftPoint.x) s.p else t.leftPoint - val rp = if(s.q.x == t.rightPoint.x) s.q else t.rightPoint - - val trapezoids = new Array[Trapezoid](2) - - if(tCross == t.top) { - trapezoids(0) = t.upperLeft - trapezoids(0).updateRight(t.upperRight, null) - trapezoids(0).rightPoint = rp - } else { - trapezoids(0) = new Trapezoid(lp, rp, t.top, s) - trapezoids(0).updateLeftRight(t.upperLeft, s.above, t.upperRight, null) - } - - if(bCross == t.bottom) { - trapezoids(1) = t.lowerLeft - trapezoids(1).updateRight(null, t.lowerRight) - trapezoids(1).rightPoint = rp - } else { - trapezoids(1) = new Trapezoid(lp, rp, s, t.bottom) - trapezoids(1).updateLeftRight(s.below, t.lowerLeft, null, t.lowerRight) - } - - bCross = t.bottom - tCross = t.top - - s.above = trapezoids(0) - s.below = trapezoids(1) - - trapezoids - } - - // Case 4: Trapezoid contains point q, p lies outside - // break trapezoid into 3 smaller trapezoids - def case4(t: Trapezoid, s: Segment) = { - - val lp = if(s.p.x == t.leftPoint.x) s.p else t.leftPoint - - val trapezoids = new Array[Trapezoid](3) - - if(tCross == t.top) { - trapezoids(0) = t.upperLeft - trapezoids(0).rightPoint = s.q - } else { - trapezoids(0) = new Trapezoid(lp, s.q, t.top, s) - trapezoids(0).updateLeft(t.upperLeft, s.above) - } - - if(bCross == t.bottom) { - trapezoids(1) = t.lowerLeft - trapezoids(1).rightPoint = s.q - } else { - trapezoids(1) = new Trapezoid(lp, s.q, s, t.bottom) - trapezoids(1).updateLeft(s.below, t.lowerLeft) - } - - trapezoids(2) = new Trapezoid(s.q, t.rightPoint, t.top, t.bottom) - trapezoids(2).updateLeftRight(trapezoids(0), trapezoids(1), t.upperRight, t.lowerRight) - - trapezoids - } - - // Create an AABB around segments - def boundingBox(segments: ArrayBuffer[Segment]): Trapezoid = { - - var max = segments(0).p + margin - var min = segments(0).q - margin - - for(s <- segments) { - if(s.p.x > max.x) max = Point(s.p.x + margin, max.y) - if(s.p.y > max.y) max = Point(max.x, s.p.y + margin) - if(s.q.x > max.x) max = Point(s.q.x+margin, max.y) - if(s.q.y > max.y) max = Point(max.x, s.q.y+margin) - if(s.p.x < min.x) min = Point(s.p.x-margin, min.y) - if(s.p.y < min.y) min = Point(min.x, s.p.y-margin) - if(s.q.x < min.x) min = Point(s.q.x-margin, min.y) - if(s.q.y < min.y) min = Point(min.x, s.q.y-margin) - } - - val top = new Segment(Point(min.x, max.y), Point(max.x, max.y)) - val bottom = new Segment(Point(min.x, min.y), Point(max.x, min.y)) - val left = bottom.p - val right = top.q - - return new Trapezoid(left, right, top, bottom) - } -} diff --git a/scala/src/org/poly2tri/seidel/Triangulator.scala b/scala/src/org/poly2tri/seidel/Triangulator.scala deleted file mode 100644 index 59e1b87..0000000 --- a/scala/src/org/poly2tri/seidel/Triangulator.scala +++ /dev/null @@ -1,228 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import scala.collection.mutable.ArrayBuffer - -import utils.{Util, Random} -import shapes.{Point, Segment, Trapezoid} - -// Based on Raimund Seidel's paper "A simple and fast incremental randomized -// algorithm for computing trapezoidal decompositions and for triangulating polygons" -// See also: "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 -// "Computational Geometry in C", 2nd edition, by Joseph O'Rourke -class Triangulator(points: ArrayBuffer[Point]) { - - // Convex polygon list - var polygons = new ArrayBuffer[Array[Point]] - // Order and randomize the segments - val segmentList = initSegments - - // The trapezoidal map - def trapezoidMap = trapezoidalMap.map - // Trapezoid decomposition list - var trapezoids = new ArrayBuffer[Trapezoid] - - // Initialize trapezoidal map and query structure - private val trapezoidalMap = new TrapezoidalMap - private val boundingBox = trapezoidalMap.boundingBox(segmentList) - private val queryGraph = new QueryGraph(Sink.init(boundingBox)) - private val xMonoPoly = new ArrayBuffer[MonotoneMountain] - - process - - // Build the trapezoidal map and query graph - private def process { - - var i = 0 - while(i < segmentList.size) { - - val s = segmentList(i) - var traps = queryGraph.followSegment(s) - - // Remove trapezoids from trapezoidal Map - var j = 0 - while(j < traps.size) { - trapezoidalMap.map -= traps(j) - j += 1 - } - - j = 0 - while(j < traps.size) { - val t = traps(j) - var tList: Array[Trapezoid] = null - val containsP = t.contains(s.p) - val containsQ = t.contains(s.q) - if(containsP && containsQ) { - // Case 1 - tList = trapezoidalMap.case1(t,s) - queryGraph.case1(t.sink, s, tList) - } else if(containsP && !containsQ) { - // Case 2 - tList = trapezoidalMap.case2(t,s) - queryGraph.case2(t.sink, s, tList) - } else if(!containsP && !containsQ) { - // Case 3 - tList = trapezoidalMap.case3(t, s) - queryGraph.case3(t.sink, s, tList) - } else { - // Case 4 - tList = trapezoidalMap.case4(t, s) - queryGraph.case4(t.sink, s, tList) - } - - // Add new trapezoids to map - var k = 0 - while(k < tList.size) { - trapezoidalMap.map += tList(k) - k += 1 - } - j += 1 - } - - trapezoidalMap.clear - i += 1 - - } - - // Mark outside trapezoids - for(t <- trapezoidalMap.map) - markOutside(t) - - // Collect interior trapezoids - for(t <- trapezoidalMap.map) - if(t.inside) { - trapezoids += t - t addPoints - } - - // Generate the triangles - createMountains - - //println("# triangles = " + triangles.size) - } - - // Monotone polygons - these are monotone mountains - def monoPolies: ArrayBuffer[ArrayBuffer[Point]] = { - val polies = new ArrayBuffer[ArrayBuffer[Point]] - for(i <- 0 until xMonoPoly.size) - polies += xMonoPoly(i).monoPoly - return polies - } - - // Build a list of x-monotone mountains - private def createMountains { - - var i = 0 - while(i < segmentList.size) { - - val s = segmentList(i) - - if(s.mPoints.size > 0) { - - val mountain = new MonotoneMountain - var k: List[Point] = null - - // Sorting is a perfromance hit. Literature says this can be accomplised in - // linear time, although I don't see a way around using traditional methods - // when using a randomized incremental algorithm - if(s.mPoints.size < 10) - // Insertion sort is one of the fastest algorithms for sorting arrays containing - // fewer than ten elements, or for lists that are already mostly sorted. - k = Util.insertSort((p1: Point, p2: Point) => p1 < p2)(s.mPoints).toList - else - k = Util.msort((p1: Point, p2: Point) => p1 < p2)(s.mPoints.toList) - - val points = s.p :: k ::: List(s.q) - var j = 0 - while(j < points.size) { - mountain += points(j) - j += 1 - } - - // Triangulate monotone mountain - mountain process - - // Extract the triangles into a single list - j = 0 - while(j < mountain.triangles.size) { - polygons += mountain.triangles(j) - j += 1 - } - - xMonoPoly += mountain - } - i += 1 - } - } - - // Mark the outside trapezoids surrounding the polygon - private def markOutside(t: Trapezoid) { - if(t.top == boundingBox.top || t.bottom == boundingBox.bottom) { - t trimNeighbors - } - } - - // Create segments and connect end points; update edge event pointer - private def initSegments: ArrayBuffer[Segment] = { - var segments = List[Segment]() - for(i <- 0 until points.size-1) - segments = new Segment(points(i), points(i+1)) :: segments - segments = new Segment(points.first, points.last) :: segments - orderSegments(segments) - } - - private def orderSegments(segments: List[Segment]) = { - - // Ignore vertical segments! - val segs = new ArrayBuffer[Segment] - for(s <- segments) { - val p = shearTransform(s.p) - val q = shearTransform(s.q) - // Point p must be to the left of point q - if(p.x > q.x) { - segs += new Segment(q, p) - } else if(p.x < q.x) { - segs += new Segment(p, q) - } - } - // Randomized triangulation improves performance - // See Seidel's paper, or O'Rourke's book, p. 57 - Random.shuffle(segs) - segs - } - - // Prevents any two distinct endpoints from lying on a common vertical line, and avoiding - // the degenerate case. See Mark de Berg et al, Chapter 6.3 - //val SHEER = 0.0001f - def shearTransform(point: Point) = Point(point.x + 0.0001f * point.y, point.y) - -} diff --git a/scala/src/org/poly2tri/seidel/XNode.scala b/scala/src/org/poly2tri/seidel/XNode.scala deleted file mode 100644 index 481ef96..0000000 --- a/scala/src/org/poly2tri/seidel/XNode.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import shapes.{Point, Segment} - -class XNode(point: Point, lChild: Node, rChild: Node) extends Node(lChild, rChild) { - - override def locate(s: Segment): Sink = { - - if(s.p.x >= point.x) { - // Move to the right in the graph - return right.locate(s) - } else { - // Move to the left in the graph - return left.locate(s) - } - } -} \ No newline at end of file diff --git a/scala/src/org/poly2tri/seidel/YNode.scala b/scala/src/org/poly2tri/seidel/YNode.scala deleted file mode 100644 index f6286ad..0000000 --- a/scala/src/org/poly2tri/seidel/YNode.scala +++ /dev/null @@ -1,55 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.seidel - -import shapes.Segment - -class YNode(segment: Segment, lChild: Node, rChild: Node) extends Node(lChild, rChild) { - - override def locate(s: Segment): Sink = { - if (segment > s.p) { - // Move down the graph - return right.locate(s) - } else if (segment < s.p) { - // Move up the graph - return left.locate(s) - } else { - // s and segment share the same endpoint, p - if (s.slope < segment.slope) { - // Move down the graph - return right.locate(s) - } else { - // Move up the graph - return left.locate(s) - } - } - } -} diff --git a/scala/src/org/poly2tri/shapes/Point.scala b/scala/src/org/poly2tri/shapes/Point.scala deleted file mode 100644 index 662c340..0000000 --- a/scala/src/org/poly2tri/shapes/Point.scala +++ /dev/null @@ -1,74 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.shapes - -import scala.collection.mutable.ArrayBuffer - -case class Point(val x: Float, val y: Float) { - - // Pointers to next and previous points in Monontone Mountain - var next, prev: Point = null - // The setment this point belongs to - var segment: Segment = null - // List of edges this point constitutes an upper ending point (CDT) - var edges = new ArrayBuffer[Segment] - - @inline def -(p: Point) = Point(x - p.x, y - p.y) - @inline def +(p: Point) = Point(x + p.x, y + p.y) - @inline def +(f: Float) = Point(x + f, y + f) - @inline def -(f: Float) = Point(x - f, y - f) - @inline def *(f: Float) = Point(x * f, y * f) - @inline def /(a: Float) = Point(x / a, y / a) - @inline def cross(p: Point) = x * p.y - y * p.x - @inline def dot(p: Point) = x * p.x + y * p.y - @inline def length = Math.sqrt(x * x + y * y).toFloat - @inline def normalize = this / length - // Sort along x axis - @inline def <(p: Point) = (x < p.x) - - // Sort along y axis - @inline def >(p: Point) = { - if(y < p.y) - true - else if(y > p.y) - false - else { - if(x < p.x) - true - else - false - } - } - - @inline def !(p: Point) = !(p.x == x && p.y == y) - @inline override def clone = Point(x, y) - -} diff --git a/scala/src/org/poly2tri/shapes/Segment.scala b/scala/src/org/poly2tri/shapes/Segment.scala deleted file mode 100644 index 2c36a9c..0000000 --- a/scala/src/org/poly2tri/shapes/Segment.scala +++ /dev/null @@ -1,78 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.shapes - -import scala.collection.mutable.ArrayBuffer - -// Represents a simple polygon's edge -// TODO: Rename this class to Edge? -class Segment(var p: Point, var q: Point) { - - // Pointers used for building trapezoidal map - var above, below: Trapezoid = null - // Montone mountain points - val mPoints = new ArrayBuffer[Point] - // Equation of a line: y = m*x + b - // Slope of the line (m) - val slope = (q.y - p.y)/(q.x - p.x) - // Y intercept - val b = p.y - (p.x * slope) - - // Determines if this segment lies above the given point - def > (point: Point) = (Math.floor(point.y) < Math.floor(slope * point.x + b)) - // Determines if this segment lies below the given point - def < (point: Point) = (Math.floor(point.y) > Math.floor(slope * point.x + b)) - - private def signedArea(a: Point, b: Point, c: Point): Float = - (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x) - - def intersect(c: Point, d: Point): Point = { - - val a = p - val b = q - - val a1 = signedArea(a, b, d) - val a2 = signedArea(a, b, c) - - if (a1 != 0.0f && a2 != 0.0f && a1*a2 < 0.0f) { - val a3 = signedArea(c, d, a) - val a4 = a3 + a2 - a1 - if (a3 * a4 < 0.0f) { - val t = a3 / (a3 - a4) - return a + ((b - a) * t) - } - } - - throw new Exception("Error") - - } - -} diff --git a/scala/src/org/poly2tri/shapes/Trapezoid.scala b/scala/src/org/poly2tri/shapes/Trapezoid.scala deleted file mode 100644 index 77f6ded..0000000 --- a/scala/src/org/poly2tri/shapes/Trapezoid.scala +++ /dev/null @@ -1,109 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.shapes - -import seidel.Sink - -class Trapezoid(val leftPoint: Point, var rightPoint: Point, val top: Segment, val bottom: Segment) { - - var sink: Sink = null - var inside = true - - // Neighbor pointers - var upperLeft: Trapezoid = null - var lowerLeft: Trapezoid = null - var upperRight: Trapezoid = null - var lowerRight: Trapezoid = null - - // Update neighbors to the left - def updateLeft(ul: Trapezoid, ll: Trapezoid) { - upperLeft = ul; if(ul != null) ul.upperRight = this - lowerLeft = ll; if(ll != null) ll.lowerRight = this - } - - // Update neighbors to the right - def updateRight(ur: Trapezoid, lr: Trapezoid) { - upperRight = ur; if(ur != null) ur.upperLeft = this - lowerRight = lr; if(lr != null) lr.lowerLeft = this - } - - // Update neighbors on both sides - def updateLeftRight(ul: Trapezoid, ll: Trapezoid, ur: Trapezoid, lr: Trapezoid) { - upperLeft = ul; if(ul != null) ul.upperRight = this - lowerLeft = ll; if(ll != null) ll.lowerRight = this - upperRight = ur; if(ur != null) ur.upperLeft = this - lowerRight = lr; if(lr != null) lr.lowerLeft = this - } - - // Recursively trim outside neighbors - def trimNeighbors { - if(inside) { - inside = false - if(upperLeft != null) upperLeft.trimNeighbors - if(lowerLeft != null) lowerLeft.trimNeighbors - if(upperRight != null) upperRight.trimNeighbors - if(lowerRight != null) lowerRight.trimNeighbors - } - } - - // Determines if this point lies inside the trapezoid - def contains(point: Point) = { - (point.x > leftPoint.x && point.x < rightPoint.x && top > point && bottom < point) - } - - def vertices: Array[Point] = { - val verts = new Array[Point](4) - verts(0) = lineIntersect(top, leftPoint.x) - verts(1) = lineIntersect(bottom, leftPoint.x) - verts(2) = lineIntersect(bottom, rightPoint.x) - verts(3) = lineIntersect(top, rightPoint.x) - verts - } - - def lineIntersect(s: Segment, x: Float) = { - val y = s.slope * x + s.b - Point(x, y) - } - - // Add points to monotone mountain - def addPoints { - if(leftPoint != bottom.p) {bottom.mPoints += leftPoint.clone} - if(rightPoint != bottom.q) {bottom.mPoints += rightPoint.clone} - if(leftPoint != top.p) {top.mPoints += leftPoint.clone} - if(rightPoint != top.q) {top.mPoints += rightPoint.clone} - } - - def debugData { - println("LeftPoint = " + leftPoint + " | RightPoint = " + rightPoint) - println("Top Segment: p = " + top.p + ", q = " + top.q) - println("Bottom Segment: p = " + bottom.p + ", q = " + bottom.q) - } -} diff --git a/scala/src/org/poly2tri/shapes/Triangle.scala b/scala/src/org/poly2tri/shapes/Triangle.scala deleted file mode 100644 index b2ace88..0000000 --- a/scala/src/org/poly2tri/shapes/Triangle.scala +++ /dev/null @@ -1,400 +0,0 @@ -/* Poly2Tri - * Copyright (c) 2009, Mason Green - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.poly2tri.shapes - -import scala.collection.mutable.ArrayBuffer - -import utils.Util - -// Triangle-based data structures are know to have better performance than quad-edge structures -// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator" -// "Triangulations in CGAL" -class Triangle(val points: Array[Point]) { - - // Neighbor pointers - var neighbors = new Array[Triangle](3) - // Flags to determine if an edge is the final Delauney edge - val edges = Array(false, false, false) - // Finalization flag. Set true if legalized or edge constrained - var finalized = false - // Has this triangle been marked as an interoir triangle? - var interior = false - - def contains(p: Point): Boolean = (p == points(0) || p == points(1) || p == points(2)) - def contains(e: Segment): Boolean = (contains(e.p) && contains(e.q)) - def contains(p: Point, q: Point): Boolean = (contains(p) && contains(q)) - - // Update neighbor pointers - private def markNeighbor(p1: Point, p2: Point, t: Triangle) { - - if((p1 == points(2) && p2 == points(1)) || (p1 == points(1) && p2 == points(2))) - neighbors(0) = t - else if((p1 == points(0) && p2 == points(2)) || (p1 == points(2) && p2 == points(0))) - neighbors(1) = t - else if((p1 == points(0) && p2 == points(1)) || (p1 == points(1) && p2 == points(0))) - neighbors(2) = t - else { - throw new Exception("Neighbor error, please report!") - } - } - - /* Exhaustive search to update neighbor pointers */ - def markNeighbor(t: Triangle) { - - if (t.contains(points(1), points(2))) { - neighbors(0) = t - t.markNeighbor(points(1), points(2), this) - } else if(t.contains(points(0), points(2))) { - neighbors(1) = t - t.markNeighbor(points(0), points(2), this) - } else if (t.contains(points(0), points(1))) { - neighbors(2) = t - t.markNeighbor(points(0), points(1), this) - } - - } - - def clearNeighbors { - neighbors = new Array[Triangle](3) - } - - def oppositePoint(t: Triangle): Point = { - - assert(t != this, "self-pointer error") - if(points(0) == t.points(1)) - points(1) - else if(points(0) == t.points(2)) - points(2) - else if(contains(t.points(1), t.points(2))) - points(0) - else { - t.printDebug - printDebug - println(area + " | " + t.area) - throw new Exception("Point location error, please report") - } - - } - - // Fast point in triangle test - def pointIn(point: Point): Boolean = { - - val ij = points(1) - points(0) - val jk = points(2) - points(1) - val pab = (point - points(0)).cross(ij) - val pbc = (point - points(1)).cross(jk) - var sameSign = Math.signum(pab) == Math.signum(pbc) - if (!sameSign) return false - - val ki = points(0) - points(2) - val pca = (point - points(2)).cross(ki) - sameSign = Math.signum(pab) == Math.signum(pca) - if (!sameSign) return false - - true - } - - // Locate first triangle crossed by constrained edge - def locateFirst(edge: Segment): Triangle = { - - if(contains(edge)) return this - - if(edge.q == points(0)) - search(points(1), points(2), edge, neighbors(2)) - else if(edge.q == points(1)) - search(points(0), points(2), edge, neighbors(0)) - else if(edge.q == points(2)) - search(points(0), points(1), edge, neighbors(1)) - else - throw new Exception("Point not found") - - } - - def search(p1: Point, p2: Point, edge: Segment, neighbor: Triangle): Triangle = { - - val o1 = Util.orient2d(edge.q, p1, edge.p) - val o2 = Util.orient2d(edge.q, p2, edge.p) - val sameSign = Math.signum(o1) == Math.signum(o2) - - // Edge crosses this triangle - if(!sameSign) - return this - - // Look at neighbor - if(neighbor == null) - null - else - neighbor.locateFirst(edge) - - } - - // Locate next triangle crossed by edge - def findNeighbor(p: Point): Triangle = { - - if(contains(p)) return this - - if(Util.orient2d(points(1), points(0), p) > 0) - return neighbors(2) - else if(Util.orient2d(points(2), points(1), p) > 0) - return neighbors(0) - else if(Util.orient2d(points(0), points(2), p) > 0) - return neighbors(1) - else - return null - - } - - // The neighbor clockwise to given point - def neighborCW(point: Point): Triangle = { - - if(point == points(0)) { - neighbors(1) - }else if(point == points(1)) { - neighbors(2) - } else - neighbors(0) - } - - // The neighbor counter-clockwise to given point - def neighborCCW(oPoint: Point): Triangle = { - - if(oPoint == points(0)) { - neighbors(2) - }else if(oPoint == points(1)) { - neighbors(0) - } else - neighbors(1) - } - - // The neighbor clockwise to given point - def neighborAcross(point: Point): Triangle = { - - if(point == points(0)) { - neighbors(0) - }else if(point == points(1)) { - neighbors(1) - } else - neighbors(2) - } - - // The point counter-clockwise to given point - def pointCCW(point: Point): Point = { - - if(point == points(0)) { - points(1) - } else if(point == points(1)) { - points(2) - } else if(point == points(2)){ - points(0) - } else { - throw new Exception("point location error") - } - } - - // The point counter-clockwise to given point - def pointCW(point: Point): Point = { - - if(point == points(0)) { - points(2) - } else if(point == points(1)) { - points(0) - } else if(point == points(2)){ - points(1) - } else { - throw new Exception("point location error") - } - } - - // Legalized triangle by rotating clockwise around point(0) - def legalize(oPoint: Point) { - - points(1) = points(0) - points(0) = points(2) - points(2) = oPoint - } - - // Legalize triagnle by rotating clockwise around oPoint - def legalize(oPoint: Point, nPoint: Point) { - - if(oPoint == points(0)) { - points(1) = points(0) - points(0) = points(2) - points(2) = nPoint - } else if (oPoint == points(1)) { - points(2) = points(1) - points(1) = points(0) - points(0) = nPoint - } else if (oPoint == points(2)) { - points(0) = points(2) - points(2) = points(1) - points(1) = nPoint - } else { - throw new Exception("legalization error") - } - - } - - // Check if legalized triangle will be collinear - def collinear(oPoint: Point): Boolean = Util.collinear(points(1), points(0), oPoint) - - // Check if legalized triangle will be collinear - def collinear(oPoint: Point, nPoint: Point): Boolean = { - - if(oPoint == points(0)) { - Util.collinear(points(0), points(2), nPoint) - } else if (oPoint == points(1)) { - Util.collinear(points(0), points(1), nPoint) - } else { - Util.collinear(points(2), points(1), nPoint) - } - } - - // Rotate neighbors clockwise around give point. Share diagnal with triangle - def rotateNeighborsCW(oPoint: Point, triangle: Triangle) { - - if(oPoint == points(0)) { - neighbors(2) = neighbors(1) - neighbors(1) = null - neighbors(0) = triangle - } else if (oPoint == points(1)) { - neighbors(0) = neighbors(2) - neighbors(2) = null - neighbors(1) = triangle - } else if (oPoint == points(2)) { - neighbors(1) = neighbors(0) - neighbors(0) = null - neighbors(2) = triangle - } else { - throw new Exception("pointer bug") - } - } - - def printDebug = println(points(0) + "," + points(1) + "," + points(2)) - - // Finalize edge marking - def markNeighborEdges { - - for(i <- 0 to 2) - if(edges(i)) - i match { - case 0 => if(neighbors(0) != null) neighbors(0).markEdge(points(1), points(2)) - case 1 => if(neighbors(1) != null) neighbors(1).markEdge(points(0), points(2)) - case 2 => if(neighbors(2) != null) neighbors(2).markEdge(points(0), points(1)) - } - } - - def markEdge(triangle: Triangle) { - - for(i <- 0 to 2) - if(edges(i)) - i match { - case 0 => triangle.markEdge(points(1), points(2)) - case 1 => triangle.markEdge(points(0), points(2)) - case 2 => triangle.markEdge(points(0), points(1)) - } - } - - def markEdge(T: ArrayBuffer[Triangle]) { - - for(t <- T) { - for(i <- 0 to 2) - if(t.edges(i)) - i match { - case 0 => markEdge(t.points(1), t.points(2)) - case 1 => markEdge(t.points(0), t.points(2)) - case 2 => markEdge(t.points(0), t.points(1)) - } - } - } - - // Mark edge as constrained - def markEdge(p: Point, q: Point) { - - if((q == points(0) && p == points(1)) || (q == points(1) && p == points(0))) { - finalized = true - edges(2) = true - } else if ((q == points(0) && p == points(2)) || (q == points(2) && p == points(0))) { - edges(1) = true - finalized = true - } else if ((q == points(1) && p == points(2)) || (q == points(2) && p == points(1))){ - finalized = true - edges(0) = true - } - } - - def area = { - - val b = points(0).x - points(1).x - val h = points(2).y - points(1).y - - Math.abs((b*h*0.5f)) - } - - def centroid: Point = { - - val cx = (points(0).x + points(1).x + points(2).x)/3f - val cy = (points(0).y + points(1).y + points(2).y)/3f - Point(cx, cy) - } - - def thin: Boolean = { - val a1 = (points(1) - points(0)) - val b1 = (points(2) - points(0)) - val a2 = (points(0) - points(1)) - val b2 = (points(2) - points(1)) - val angle1 = Math.abs(Math.atan2(a1 cross b1, a1 dot b1)) - val angle2 = Math.abs(Math.atan2(a2 cross b2, a2 dot b2)) - val angle3 = Math.Pi - angle1 - angle2 - // 30 degrees - val minAngle = Math.Pi/6 - (angle1 <= minAngle || angle2 <= minAngle || angle3 <= minAngle) - } - - // Compute barycentric coordinates (u, v, w) for - // point p with respect to triangle - // From "Real-Time Collision Detection" by Christer Ericson - def barycentric(p: Point): List[Float] = { - val v0 = points(1) - points(0) - val v1 = points(2) - points(0) - val v2 = p - points(0) - val d00 = v0 dot v0 - val d01 = v0 dot v1 - val d11 = v1 dot v1 - val d20 = v2 dot v0 - val d21 = v2 dot v1 - val denom = d00 * d11 - d01 * d01 - val v = (d11 * d20 - d01 * d21) / denom - val w = (d00 * d21 - d01 * d20) / denom - val u = 1.0f - v - w - List(u, v, w) - } - -} diff --git a/scala/src/org/poly2tri/utils/Util.scala b/scala/src/org/poly2tri/utils/Util.scala deleted file mode 100644 index cd3e3a6..0000000 --- a/scala/src/org/poly2tri/utils/Util.scala +++ /dev/null @@ -1,339 +0,0 @@ - -package org.poly2tri.utils - -import scala.collection.mutable.ArrayBuffer - -import shapes.Point - -object Util { - - // Almost zero - val COLLINEAR_SLOP = 0.1f - - val epsilon = exactinit - val ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon - val iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon - - // Refursive merge sort, from "Scala By Example," by Martin Odersky - def msort[A](less: (A, A) => Boolean)(xs: List[A]): List[A] = { - def merge(xs1: List[A], xs2: List[A]): List[A] = - if (xs1.isEmpty) xs2 - else if (xs2.isEmpty) xs1 - else if (less(xs1.head, xs2.head)) xs1.head :: merge(xs1.tail, xs2) - else xs2.head :: merge(xs1, xs2.tail) - val n = xs.length/2 - if (n == 0) xs - else merge(msort(less)(xs take n), msort(less)(xs drop n)) - } - - // Insertion sort - best for lists <= 10 elements - def insertSort[A](less: (A, A) => Boolean)(xs: ArrayBuffer[A]): ArrayBuffer[A] = { - var j = 1 - while(j < xs.size){ - val key = xs(j) - var i = j-1 - while(i >= 0 && less(key, xs(i)) ){ - xs(i+1) = xs(i) - i -= 1 - } - xs(i+1)=key - j += 1 - } - xs - } - - // Tests if the given points are collinear - def collinear(p1: Point, p2: Point, p3: Point): Boolean = { - - val d = Math.abs((p2-p1) cross (p1-p3)) - - if(d <= COLLINEAR_SLOP) - true - else - false - - } - - /* From Jonathan Shewchuk's "Adaptive Precision Floating-Point Arithmetic - * and Fast Robust Predicates for Computational Geometry" - * See: http://www.cs.cmu.edu/~quake/robust.html - */ - def exactinit = { - - var every_other = true - var half = 0.5 - var splitter = 1.0 - var epsilon = 1.0 - var check = 1.0 - var lastcheck = 0.0 - - do { - lastcheck = check - epsilon *= half - if (every_other) { - splitter *= 2.0 - } - every_other = !every_other - check = 1.0 + epsilon - } while ((check != 1.0) && (check != lastcheck)) - - epsilon - - } - - // Approximate 2D orientation test. Nonrobust. - // Return: positive if point a, b, and c are counterclockwise - // negative if point a, b, and c are clockwise - // zero if points are collinear - // See: http://www-2.cs.cmu.edu/~quake/robust.html - def orient(a: Point, b: Point, p: Point): Float = { - val acx = a.x - p.x - val bcx = b.x - p.x - val acy = a.y - p.y - val bcy = b.y - p.y - acx * bcy - acy * bcx - } - - // Adaptive exact 2D orientation test. Robust. By Jonathan Shewchuk - // Return: positive if point a, b, and c are counterclockwise - // negative if point a, b, and c are clockwise - // zero if points are collinear - // See: http://www-2.cs.cmu.edu/~quake/robust.html - def orient2d(pa: Point, pb: Point, pc: Point): Double = { - - val detleft: Double = (pa.x - pc.x) * (pb.y - pc.y) - val detright: Double = (pa.y - pc.y) * (pb.x - pc.x) - val det = detleft - detright - var detsum = 0.0 - - if (detleft > 0.0) { - if (detright <= 0.0) { - return det; - } else { - detsum = detleft + detright - } - } else if (detleft < 0.0) { - if (detright >= 0.0) { - return det - } else { - detsum = -detleft - detright - } - } else { - return det - } - - val errbound = ccwerrboundA * detsum - if ((det >= errbound) || (-det >= errbound)) { - return det - } else { - // Cheat a little bit.... we have a degenerate triangle - val c = pc * 0.1e-6f - return orient2d(pa, pb, c) - } - - } - - // Original by Jonathan Shewchuk - // http://www.ics.uci.edu/~eppstein/junkyard/circumcenter.html - def circumcenter(a: Point, b: Point, c: Point): Point = { - - /* Use coordinates relative to point `a' of the triangle. */ - val xba = b.x - a.x - val yba = b.y - a.y - val xca = c.x - a.x - val yca = c.y - a.y - /* Squares of lengths of the edges incident to `a'. */ - val balength = xba * xba + yba * yba - val calength = xca * xca + yca * yca - - /* Calculate the denominator of the formulae. */ - val denominator = 0.5 / orient2d(b, c, a) - - /* Calculate offset (from `a') of circumcenter. */ - val xcirca = (yca * balength - yba * calength) * denominator - val ycirca = (xba * calength - xca * balength) * denominator - - a + Point(xcirca.toFloat, ycirca.toFloat) - - } - - // Returns triangle circumcircle point and radius - def circumCircle(a: Point, b: Point, c: Point): Tuple2[Point, Float] = { - - val A = det(a, b, c) - val C = detC(a, b, c) - - val bx1 = Point(a.x*a.x + a.y*a.y, a.y) - val bx2 = Point(b.x*b.x + b.y*b.y, b.y) - val bx3 = Point(c.x*c.x + c.y*c.y, c.y) - val bx = det(bx1, bx2, bx3) - - val by1 = Point(a.x*a.x + a.y*a.y, a.x) - val by2 = Point(b.x*b.x + b.y*b.y, b.x) - val by3 = Point(c.x*c.x + c.y*c.y, c.x) - val by = det(by1, by2, by3) - - val x = bx / (2*A) - val y = by / (2*A) - - val center = Point(x, y) - val radius = Math.sqrt(bx*bx + by*by - 4*A*C).toFloat / (2*Math.abs(A)) - - (center, radius) - } - - private def det(p1: Point, p2: Point, p3: Point): Float = { - - val a11 = p1.x - val a12 = p1.y - val a13,a23,a33 = 1f - val a21 = p2.x - val a22 = p2.y - val a31 = p3.x - val a32 = p3.y - - a11*(a22*a33-a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32-a22*a31) - - } - - private def detC(p1: Point, p2: Point, p3: Point): Float = { - - val a11 = p1.x*p1.x + p1.y*p1.y - val a12 = p1.x - val a13 = p1.y - val a21 = p2.x*p2.x + p2.y*p2.y - val a22 = p2.x - val a23 = p2.y - val a31 = p3.x*p3.x + p3.y*p3.y - val a32 = p3.x - val a33 = p3.y - - a11*(a22*a33-a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32-a22*a31) - - } - - /* Approximate 2D incircle test. Nonrobust. By Jonathan Shewchuk - * Return a positive value if the point pd lies inside the - * circle passing through pa, pb, and pc; a negative value if - * it lies outside; and zero if the four points are cocircular. - * The points pa, pb, and pc must be in counterclockwise - * order, or the sign of the result will be reversed. - */ - def incirclefast(pa: Point, pb: Point, pc: Point, pd: Point): Boolean = { - - val adx = pa.x - pd.x - val ady = pa.y - pd.y - val bdx = pb.x - pd.x - val bdy = pb.y - pd.y - val cdx = pc.x - pd.x - val cdy = pc.y - pd.y - - val abdet = adx * bdy - bdx * ady - val bcdet = bdx * cdy - cdx * bdy - val cadet = cdx * ady - adx * cdy - val alift = adx * adx + ady * ady - val blift = bdx * bdx + bdy * bdy - val clift = cdx * cdx + cdy * cdy - - alift * bcdet + blift * cadet + clift * abdet >= 0 - - } - - /* Robust 2D incircle test, modified. Original By Jonathan Shewchuk - * Return a positive value if the point pd lies inside the - * circle passing through pa, pb, and pc; a negative value if - * it lies outside; and zero if the four points are cocircular. - * The points pa, pb, and pc must be in counterclockwise - * order, or the sign of the result will be reversed. - */ - def incircle(pa: Point, pb: Point, pc: Point, pd: Point): Boolean = { - - val adx = pa.x - pd.x - val bdx = pb.x - pd.x - val cdx = pc.x - pd.x - val ady = pa.y - pd.y - val bdy = pb.y - pd.y - val cdy = pc.y - pd.y - - val bdxcdy = bdx * cdy - val cdxbdy = cdx * bdy - val alift = adx * adx + ady * ady - - val cdxady = cdx * ady - val adxcdy = adx * cdy - val blift = bdx * bdx + bdy * bdy - - val adxbdy = adx * bdy - val bdxady = bdx * ady - val clift = cdx * cdx + cdy * cdy - - val det = alift * (bdxcdy - cdxbdy) + - blift * (cdxady - adxcdy) + - clift * (adxbdy - bdxady) - - val permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift + - (Math.abs(cdxady) + Math.abs(adxcdy)) * blift + - (Math.abs(adxbdy) + Math.abs(bdxady)) * clift - - val errbound = iccerrboundA * permanent - - if ((det > errbound) || (-det > errbound)) { - return det >= 0 - } else { - // Cheat a little bit.... we have a degenerate triangle - val d = pd * 0.1e-6f - return incircle(pa, pb, pc, d) - } - - } - - def closestPtSegment(c: Point, a: Point, b: Point): Point = { - val ab = b - a - var t = (c - a) dot ab - if (t <= 0.0f) - return a - else { - val denom = ab dot ab - if (t >= denom) - return b - else { - t = t / denom - } - } - a + (ab * t) - } - -} - -/** The object Random offers a default implementation - * of scala.util.Random and random-related convenience methods. - * - * @since 2.8 - * From Scala 2.8 standard library - */ -object Random extends scala.util.Random { - - /** Returns a new sequence in random order. - * @param seq the sequence to shuffle - * @return the shuffled sequence - */ - def shuffle[T](buf: ArrayBuffer[T]): ArrayBuffer[T] = { - // It would be better if this preserved the shape of its container, but I have - // again been defeated by the lack of higher-kinded type inference. I can - // only make it work that way if it's called like - // shuffle[Int,List](List.range(0,100)) - // which nicely defeats the "convenience" portion of "convenience method". - - def swap(i1: Int, i2: Int) { - val tmp = buf(i1) - buf(i1) = buf(i2) - buf(i2) = tmp - } - - for (n <- buf.length to 2 by -1) { - val k = nextInt(n) - swap(n - 1, k) - } - buf - } -}