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 @@
-
-
-
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 @@
-
-
-
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
- }
-}