tmp update

This commit is contained in:
张壹 2021-10-15 16:53:12 +08:00
parent e3812057b7
commit 10bb022a07
20 changed files with 44068 additions and 122 deletions

View File

@ -1975,8 +1975,8 @@
1974 1.4206 1974 1.4206
1975 1.1363 1975 1.1363
1976 1.136 1976 1.136
1977 1.136 1977 1.4285
1978 1.4285 1978 1.136
1979 1.1355 1979 1.1355
1980 1.1352 1980 1.1352
1981 1.69885 1981 1.69885
@ -2075,8 +2075,8 @@
2074 1.49957 2074 1.49957
2075 1.07982 2075 1.07982
2076 1.0787 2076 1.0787
2077 1.29195 2077 1.0787
2078 1.0787 2078 1.29195
2079 1.07857 2079 1.07857
2080 1.72454 2080 1.72454
2081 1.0785 2081 1.0785

View File

@ -1982,9 +1982,9 @@ $Nodes
1977 350 750 84.5986 1977 350 750 84.5986
1978 330 750 89.6465 1978 330 750 89.6465
1979 240 570 45.0428 1979 240 570 45.0428
1980 700 420 115.744 1980 520 470 168.821
1981 520 470 168.821 1981 510 470 168.277
1982 510 470 168.277 1982 700 420 115.744
1983 260 800 53.4204 1983 260 800 53.4204
1984 910 280 26.9883 1984 910 280 26.9883
1985 900 260 26.7625 1985 900 260 26.7625
@ -2082,9 +2082,9 @@ $Nodes
2077 620 20 12.1613 2077 620 20 12.1613
2078 600 40 16.9786 2078 600 40 16.9786
2079 890 80 19.6648 2079 890 80 19.6648
2080 880 300 34.2451 2080 480 760 36.4966
2081 900 300 29.6101 2081 880 300 34.2451
2082 480 760 36.4966 2082 900 300 29.6101
2083 690 240 61.8001 2083 690 240 61.8001
2084 700 220 52.8594 2084 700 220 52.8594
2085 730 620 29.0292 2085 730 620 29.0292
@ -2532,7 +2532,7 @@ $Elements
273 2 0 412 513 1200 273 2 0 412 513 1200
274 2 0 413 513 412 274 2 0 413 513 412
275 2 0 561 514 75 275 2 0 561 514 75
276 2 0 47 1982 528 276 2 0 47 1981 528
277 2 0 220 753 515 277 2 0 220 753 515
278 2 0 410 810 260 278 2 0 410 810 260
279 2 0 748 516 148 279 2 0 748 516 148
@ -2801,7 +2801,7 @@ $Elements
542 2 0 700 701 55 542 2 0 700 701 55
543 2 0 1084 314 1197 543 2 0 1084 314 1197
544 2 0 231 703 493 544 2 0 231 703 493
545 2 0 1980 704 1040 545 2 0 1982 704 1040
546 2 0 243 704 284 546 2 0 243 704 284
547 2 0 596 425 705 547 2 0 596 425 705
548 2 0 636 52 706 548 2 0 636 52 706
@ -3650,7 +3650,7 @@ $Elements
1391 2 0 2186 1154 201 1391 2 0 2186 1154 201
1392 2 0 391 1245 1408 1392 2 0 391 1245 1408
1393 2 0 391 1408 392 1393 2 0 391 1408 392
1394 2 0 527 1982 1155 1394 2 0 527 1981 1155
1395 2 0 434 527 1155 1395 2 0 434 527 1155
1396 2 0 539 887 1156 1396 2 0 539 887 1156
1397 2 0 10 1138 1157 1397 2 0 10 1138 1157
@ -3684,7 +3684,7 @@ $Elements
1425 2 0 952 951 1168 1425 2 0 952 951 1168
1426 2 0 124 1148 1168 1426 2 0 124 1148 1168
1427 2 0 1917 1169 201 1427 2 0 1917 1169 201
1428 2 0 2082 2008 1354 1428 2 0 2080 2008 1354
1429 2 0 916 1170 154 1429 2 0 916 1170 154
1430 2 0 64 1461 916 1430 2 0 64 1461 916
1431 2 0 1038 192 1171 1431 2 0 1038 192 1171
@ -5202,7 +5202,7 @@ $Elements
2943 2 0 1372 1760 1595 2943 2 0 1372 1760 1595
2944 2 0 286 1760 1371 2944 2 0 286 1760 1371
2945 2 0 1817 1760 286 2945 2 0 1817 1760 286
2946 2 0 1980 1761 536 2946 2 0 1982 1761 536
2947 2 0 2029 1761 1039 2947 2 0 2029 1761 1039
2948 2 0 1214 1761 1040 2948 2 0 1214 1761 1040
2949 2 0 817 1761 1214 2949 2 0 817 1761 1214
@ -5835,15 +5835,15 @@ $Elements
3576 2 0 566 1979 898 3576 2 0 566 1979 898
3577 2 0 1317 1979 228 3577 2 0 1317 1979 228
3578 2 0 898 1979 1317 3578 2 0 898 1979 1317
3579 2 0 284 704 1980 3579 2 0 455 1980 47
3580 2 0 1040 1761 1980 3580 2 0 456 1980 455
3581 2 0 536 284 1980 3581 2 0 1980 1981 47
3582 2 0 455 1981 47 3582 2 0 528 1981 527
3583 2 0 456 1981 455 3583 2 0 456 1981 1980
3584 2 0 1981 1982 47 3584 2 0 1155 1981 456
3585 2 0 528 1982 527 3585 2 0 284 704 1982
3586 2 0 456 1982 1981 3586 2 0 1040 1761 1982
3587 2 0 1155 1982 456 3587 2 0 536 284 1982
3588 2 0 381 1605 1983 3588 2 0 381 1605 1983
3589 2 0 1374 1375 1983 3589 2 0 1374 1375 1983
3590 2 0 1375 1876 1983 3590 2 0 1375 1876 1983
@ -5986,7 +5986,7 @@ $Elements
3727 2 0 1505 2027 649 3727 2 0 1505 2027 649
3728 2 0 2237 2027 1477 3728 2 0 2237 2027 1477
3729 2 0 386 2027 1505 3729 2 0 386 2027 1505
3730 2 0 2080 2027 386 3730 2 0 2081 2027 386
3731 2 0 112 2028 1324 3731 2 0 112 2028 1324
3732 2 0 1324 2028 467 3732 2 0 1324 2028 467
3733 2 0 780 2028 112 3733 2 0 780 2028 112
@ -6147,17 +6147,17 @@ $Elements
3888 2 0 1234 2079 1221 3888 2 0 1234 2079 1221
3889 2 0 1220 2079 712 3889 2 0 1220 2079 712
3890 2 0 1221 2079 1773 3890 2 0 1221 2079 1773
3891 2 0 2027 2080 1477 3891 2 0 1143 417 2080
3892 2 0 1477 2080 830 3892 2 0 417 2008 2080
3893 2 0 1984 2081 386 3893 2 0 1354 1143 2080
3894 2 0 830 2080 627 3894 2 0 2027 2081 1477
3895 2 0 1941 2081 1984 3895 2 0 1477 2081 830
3896 2 0 386 2081 2080 3896 2 0 1984 2082 386
3897 2 0 627 2081 1941 3897 2 0 830 2081 627
3898 2 0 2080 2081 627 3898 2 0 1941 2082 1984
3899 2 0 1143 417 2082 3899 2 0 386 2082 2081
3900 2 0 417 2008 2082 3900 2 0 627 2082 1941
3901 2 0 1354 1143 2082 3901 2 0 2081 2082 627
3902 2 0 253 1693 2083 3902 2 0 253 1693 2083
3903 2 0 769 253 2083 3903 2 0 769 253 2083
3904 2 0 770 1801 2084 3904 2 0 770 1801 2084
@ -8693,9 +8693,9 @@ $NodeData
1977 84.5986 1977 84.5986
1978 89.6465 1978 89.6465
1979 45.0428 1979 45.0428
1980 115.744 1980 168.821
1981 168.821 1981 168.277
1982 168.277 1982 115.744
1983 53.4204 1983 53.4204
1984 26.9883 1984 26.9883
1985 26.7625 1985 26.7625
@ -8793,9 +8793,9 @@ $NodeData
2077 12.1613 2077 12.1613
2078 16.9786 2078 16.9786
2079 19.6648 2079 19.6648
2080 34.2451 2080 36.4966
2081 29.6101 2081 34.2451
2082 36.4966 2082 29.6101
2083 61.8001 2083 61.8001
2084 52.8594 2084 52.8594
2085 29.0292 2085 29.0292

View File

@ -199,7 +199,7 @@
198 22 1023 197 198 22 1023 197
199 1985 483 3758 199 1985 483 3758
200 510 511 201 200 510 511 201
201 200 504 3582 201 200 504 3579
202 291 1395 175 202 291 1395 175
203 400 2249 205 203 400 2249 205
204 88 34 2248 204 88 34 2248
@ -274,7 +274,7 @@
273 274 1498 2688 273 274 1498 2688
274 773 273 152 274 773 273 152
275 344 128 342 275 344 128 342
276 3584 3585 292 276 3581 3582 292
277 622 624 396 277 622 624 396
278 706 704 1929 278 706 704 1929
279 612 2848 610 279 612 2848 610
@ -288,10 +288,10 @@
287 2709 418 2442 287 2709 418 2442
288 1044 289 816 288 1044 289 816
289 1401 288 606 289 1401 288 606
290 249 1633 3587 290 249 1633 3584
291 64 293 202 291 64 293 202
292 510 276 4446 292 510 276 4446
293 291 2469 3585 293 291 2469 3582
294 1051 901 478 294 1051 901 478
295 647 788 375 295 647 788 375
296 930 297 456 296 930 297 456
@ -543,8 +543,8 @@
542 540 541 538 542 540 541 538
543 1235 1490 3644 543 1235 1490 3644
544 2598 2813 781 544 2598 2813 781
545 3579 1135 3580 545 3585 1135 3586
546 1099 3579 72 546 1099 3585 72
547 1507 386 996 547 1507 386 996
548 1883 446 447 548 1883 446 447
549 4288 2612 4289 549 4288 2612 4289
@ -597,7 +597,7 @@
596 984 338 842 596 984 338 842
597 850 598 72 597 850 598 72
598 597 849 32 598 597 849 32
599 848 850 3581 599 848 850 3587
600 602 601 216 600 602 601 216
601 600 2625 3812 601 600 2625 3812
602 2626 600 357 602 2626 600 357
@ -1259,7 +1259,7 @@
1258 3833 4286 2277 1258 3833 4286 2277
1259 2048 1362 4259 1259 2048 1362 4259
1260 1261 2049 648 1260 1261 2049 648
1261 1362 1260 3899 1261 1362 1260 3891
1262 1264 1263 472 1262 1264 1263 472
1263 1262 1265 414 1263 1262 1265 414
1264 1265 1262 1194 1264 1265 1262 1194
@ -1358,7 +1358,7 @@
1357 1355 3322 365 1357 1355 3322 365
1358 1582 2287 2286 1358 1582 2287 2286
1359 1153 1678 1676 1359 1153 1678 1676
1360 1361 3901 155 1360 1361 3893 155
1361 1362 1360 2277 1361 1362 1360 2277
1362 1261 1361 1259 1362 1261 1361 1259
1363 2918 1364 430 1363 2918 1364 430
@ -1392,7 +1392,7 @@
1391 2238 3399 4230 1391 2238 3399 4230
1392 2416 2646 1393 1392 2416 2646 1393
1393 1392 1971 2881 1393 1392 1971 2881
1394 3585 3587 1395 1394 3582 3584 1395
1395 202 1394 177 1395 202 1394 177
1396 1224 54 2140 1396 1224 54 2140
1397 1349 2184 1398 1397 1349 2184 1398
@ -1426,7 +1426,7 @@
1425 686 967 1424 1425 686 967 1424
1426 1375 685 967 1426 1375 685 967
1427 3400 3661 3399 1427 3400 3661 3399
1428 3900 3662 3901 1428 3892 3662 3893
1429 1504 5 1403 1429 1504 5 1403
1430 2112 2114 897 1430 2112 2114 897
1431 1134 69 3468 1431 1134 69 3468
@ -2158,7 +2158,7 @@
2157 2156 1743 3541 2157 2156 1743 3541
2158 2159 2509 354 2158 2159 2509 354
2159 1743 2158 1741 2159 1743 2158 1741
2160 3857 4415 3892 2160 3857 4415 3895
2161 2163 2162 3264 2161 2163 2162 3264
2162 2161 2164 2662 2162 2161 2164 2662
2163 102 2161 241 2163 102 2161 241
@ -2498,7 +2498,7 @@
2497 919 2495 2243 2497 919 2495 2243
2498 2500 2499 1003 2498 2500 2499 1003
2499 2498 2501 353 2499 2498 2501 353
2500 2501 2498 3583 2500 2501 2498 3580
2501 2499 2500 502 2501 2499 2500 502
2502 458 2504 2400 2502 458 2504 2400
2503 2506 458 4280 2503 2506 458 4280
@ -2944,9 +2944,9 @@
2943 3083 3101 2471 2943 3083 3101 2471
2944 2945 3082 1872 2944 2945 3082 1872
2945 3101 2944 3100 2945 3101 2944 3100
2946 3580 3736 3581 2946 3586 3736 3587
2947 3736 497 3737 2947 3736 497 3737
2948 2949 3580 1530 2948 2949 3586 1530
2949 497 2948 1531 2949 497 2948 1531
2950 2952 1380 1006 2950 2952 1380 1006
2951 1380 2953 1382 2951 1380 2953 1382
@ -3463,7 +3463,7 @@
3462 3461 3464 1208 3462 3461 3464 1208
3463 3464 3461 3266 3463 3464 3461 3266
3464 3462 3463 995 3464 3462 3463 995
3465 3853 3897 2080 3465 3853 3900 2080
3466 133 2080 3591 3466 133 2080 3591
3467 3469 3468 1436 3467 3469 3468 1436
3468 3467 3470 1431 3468 3467 3470 1431
@ -3577,23 +3577,23 @@
3576 3575 3578 957 3576 3575 3578 957
3577 3578 643 2119 3577 3578 643 2119
3578 3576 3577 2320 3578 3576 3577 2320
3579 546 545 3581 3579 3580 3581 201
3580 2948 2946 545 3580 3583 3579 2500
3581 599 3579 2946 3581 3583 276 3579
3582 3583 3584 201 3582 276 1394 293
3583 3586 3582 2500 3583 3584 3581 3580
3584 3586 276 3582 3584 1394 3583 290
3585 276 1394 293 3585 546 545 3587
3586 3587 3584 3583 3586 2948 2946 545
3587 1394 3586 290 3587 599 3585 2946
3588 4057 1878 3273 3588 4057 1878 3273
3589 2741 3590 1878 3589 2741 3590 1878
3590 3280 3273 3589 3590 3280 3273 3589
3591 3895 3695 3466 3591 3898 3695 3466
3592 3594 3595 2236 3592 3594 3595 2236
3593 3695 3595 3696 3593 3695 3595 3696
3594 2004 3692 3592 3594 2004 3692 3592
3595 3893 3592 3593 3595 3896 3592 3593
3596 3598 3597 1108 3596 3598 3597 1108
3597 3596 3599 2835 3597 3596 3599 2835
3598 1650 3596 1652 3598 1650 3596 1652
@ -3661,7 +3661,7 @@
3660 3658 3659 1582 3660 3658 3659 1582
3661 1427 3662 3663 3661 1427 3662 3663
3662 1832 1428 3661 3662 1832 1428 3661
3663 799 3661 3900 3663 799 3661 3892
3664 3529 3863 3862 3664 3529 3863 3862
3665 248 3666 3865 3665 248 3666 3865
3666 3207 3667 3665 3666 3207 3667 3665
@ -3726,9 +3726,9 @@
3725 2787 2786 2617 3725 2787 2786 2617
3726 1096 4438 4439 3726 1096 4438 4439
3727 3729 4402 2235 3727 3729 4402 2235
3728 4402 3891 4403 3728 4402 3894 4403
3729 3730 3727 2236 3729 3730 3727 2236
3730 3891 3729 3896 3730 3894 3729 3899
3731 3733 3732 4093 3731 3733 3732 4093
3732 3731 3734 520 3732 3731 3734 520
3733 3734 3731 3683 3733 3734 3731 3683
@ -3856,7 +3856,7 @@
3855 3857 3856 2530 3855 3857 3856 2530
3856 3855 2529 3854 3856 3855 2529 3854
3857 3858 3855 2160 3857 3858 3855 2160
3858 2529 3857 3894 3858 2529 3857 3897
3859 1657 4335 1389 3859 1657 4335 1389
3860 3505 1658 4335 3860 3505 1658 4335
3861 3007 1389 1658 3861 3007 1389 1658
@ -3889,17 +3889,17 @@
3888 3887 3890 3819 3888 3887 3890 3819
3889 1538 1568 2770 3889 1538 1568 2770
3890 3888 1538 2982 3890 3888 1538 2982
3891 3730 3892 3728 3891 1261 3892 3893
3892 3891 3894 2160 3892 3663 1428 3891
3893 3895 3896 3595 3893 1360 3891 1428
3894 3892 3898 3858 3894 3730 3895 3728
3895 3897 3893 3591 3895 3894 3897 2160
3896 3893 3898 3730 3896 3898 3899 3595
3897 3898 3895 3465 3897 3895 3901 3858
3898 3896 3897 3894 3898 3900 3896 3591
3899 1261 3900 3901 3899 3896 3901 3730
3900 3663 1428 3899 3900 3901 3898 3465
3901 1360 3899 1428 3901 3899 3900 3897
3902 2747 2746 3903 3902 2747 2746 3903
3903 3640 3902 1136 3903 3640 3902 1136
3904 3202 3057 2768 3904 3202 3057 2768

2249
data/topo_TIN2.log Normal file

File diff suppressed because it is too large Load Diff

8718
data/topo_TIN2.msh Normal file

File diff suppressed because it is too large Load Diff

4198
data/topo_TIN2.neigh Normal file

File diff suppressed because it is too large Load Diff

8000
data/topo_rnd Normal file

File diff suppressed because it is too large Load Diff

1439
data/topo_rnd_TIN.log Normal file

File diff suppressed because it is too large Load Diff

5749
data/topo_rnd_TIN.msh Normal file

File diff suppressed because it is too large Load Diff

2857
data/topo_rnd_TIN.neigh Normal file

File diff suppressed because it is too large Load Diff

1439
data/topo_rnd_TIN2.log Normal file

File diff suppressed because it is too large Load Diff

5704
data/topo_rnd_TIN2.msh Normal file

File diff suppressed because it is too large Load Diff

2812
data/topo_rnd_TIN2.neigh Normal file

File diff suppressed because it is too large Load Diff

View File

@ -66,3 +66,6 @@ macro(add_demo name)
endmacro() endmacro()
add_demo(demo) add_demo(demo)
add_demo(demo2)
add_demo(demo3)
add_demo(demo4)

View File

@ -17,7 +17,7 @@ int main(int argc, char const *argv[])
std::vector<double> err_records; std::vector<double> err_records;
std::vector<vertex2dc*> tin_vert; std::vector<vertex2dc*> tin_vert;
std::vector<triangle*> tin_ele; std::vector<triangle*> tin_ele;
dem2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, &err_records); dem2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records);
// Write a log file // Write a log file
std::ofstream logfile("data/topo_TIN.log"); std::ofstream logfile("data/topo_TIN.log");

94
src/demo/demo2.cpp Normal file
View File

@ -0,0 +1,94 @@
#include "../lib/tin.h"
#include "iostream"
#include "fstream"
#include "iomanip"
int main(int argc, char const *argv[])
{
// read dem grid
std::vector<dem_point> topo(8000);
std::ifstream infile("data/topo_rnd");
for (int i = 0; i < 8000; ++i)
{
infile >> topo[i].x >> topo[i].y >> topo[i].elev;
}
infile.close();
std::vector<double> err_records;
std::vector<vertex2dc*> tin_vert;
std::vector<triangle*> tin_ele;
rnd2tin(topo, tin_vert, tin_ele, 1.0, nullptr, &err_records);
// Write a log file
std::ofstream logfile("data/topo_rnd_TIN.log");
logfile << "# Insertion Maxi-Error\n";
for (int i = 0; i < err_records.size(); ++i)
{
logfile << i+1 << " " << err_records[i] << std::endl;
}
logfile.close();
// Write a Gmsh's .msh file
std::ofstream outfile("data/topo_rnd_TIN.msh");
outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<<std::endl;
outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16)
<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
}
outfile<<"$EndNodes"<<std::endl;
outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1 << " 2 0";
for (int j = 0; j < 3; j++)
{
outfile << " " << tin_ele[i]->vert[j]->id + 1;
}
outfile << std::endl;
}
outfile << "$EndElements"<< std::endl;
outfile<<"$NodeData"<<std::endl;
outfile<<1<<std::endl
<<"\"Topography (m)\"" <<std::endl
<< 1 <<std::endl<< 0.0 <<std::endl
<< 3 <<std::endl<< 0<<std::endl
<< 1 <<std::endl<< tin_vert.size() <<std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl;
}
outfile << "$EndNodeData" << std::endl;
outfile.close();
// write a neighbor file
outfile.open("data/topo_rnd_TIN.neigh");
outfile << tin_ele.size() << std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1;
for (int j = 0; j < 3; j++)
{
if (tin_ele[i]->neigh[j] != nullptr)
{
outfile << " " << tin_ele[i]->neigh[j]->id + 1;
}
else outfile << " -1";
}
outfile << std::endl;
}
outfile.close();
// Destroy memories allocated by the dem2tin function
for (int i = 0; i < tin_vert.size(); ++i)
{
delete tin_vert[i];
}
for (int i = 0; i < tin_ele.size(); ++i)
{
delete tin_ele[i];
}
return 0;
}

105
src/demo/demo3.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "../lib/tin.h"
#include "iostream"
#include "fstream"
#include "iomanip"
int main(int argc, char const *argv[])
{
// read dem grid
std::vector<double> topo(10201);
std::ifstream infile("data/topo");
for (int i = 0; i < 10201; ++i)
{
infile >> topo[i];
}
infile.close();
// Set outline polygon
std::vector<vertex2dc> valid_area(8);
valid_area[0].set(0, 500, 0, 0);
valid_area[1].set(58, 365, 0, 1);
valid_area[2].set(314, 158, 0, 2);
valid_area[3].set(681, 22, 0, 3);
valid_area[4].set(942, 105, 0, 4);
valid_area[5].set(1000, 360, 0, 5);
valid_area[6].set(1000, 1000, 0, 6);
valid_area[7].set(0, 1000, 0, 7);
std::vector<double> err_records;
std::vector<vertex2dc*> tin_vert;
std::vector<triangle*> tin_ele;
dem2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, &valid_area, &err_records);
// Write a log file
std::ofstream logfile("data/topo_TIN2.log");
logfile << "# Insertion Maxi-Error\n";
for (int i = 0; i < err_records.size(); ++i)
{
logfile << i+1 << " " << err_records[i] << std::endl;
}
logfile.close();
// Write a Gmsh's .msh file
std::ofstream outfile("data/topo_TIN2.msh");
outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<<std::endl;
outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16)
<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
}
outfile<<"$EndNodes"<<std::endl;
outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1 << " 2 0";
for (int j = 0; j < 3; j++)
{
outfile << " " << tin_ele[i]->vert[j]->id + 1;
}
outfile << std::endl;
}
outfile << "$EndElements"<< std::endl;
outfile<<"$NodeData"<<std::endl;
outfile<<1<<std::endl
<<"\"Topography (m)\"" <<std::endl
<< 1 <<std::endl<< 0.0 <<std::endl
<< 3 <<std::endl<< 0<<std::endl
<< 1 <<std::endl<< tin_vert.size() <<std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl;
}
outfile << "$EndNodeData" << std::endl;
outfile.close();
// write a neighbor file
outfile.open("data/topo_TIN2.neigh");
outfile << tin_ele.size() << std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1;
for (int j = 0; j < 3; j++)
{
if (tin_ele[i]->neigh[j] != nullptr)
{
outfile << " " << tin_ele[i]->neigh[j]->id + 1;
}
else outfile << " -1";
}
outfile << std::endl;
}
outfile.close();
// Destroy memories allocated by the dem2tin function
for (int i = 0; i < tin_vert.size(); ++i)
{
delete tin_vert[i];
}
for (int i = 0; i < tin_ele.size(); ++i)
{
delete tin_ele[i];
}
return 0;
}

105
src/demo/demo4.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "../lib/tin.h"
#include "iostream"
#include "fstream"
#include "iomanip"
int main(int argc, char const *argv[])
{
// read dem grid
std::vector<dem_point> topo(8000);
std::ifstream infile("data/topo_rnd");
for (int i = 0; i < 8000; ++i)
{
infile >> topo[i].x >> topo[i].y >> topo[i].elev;
}
infile.close();
// Set outline polygon
std::vector<vertex2dc> valid_area(8);
valid_area[0].set(0, 500, 0, 0);
valid_area[1].set(58, 365, 0, 1);
valid_area[2].set(314, 158, 0, 2);
valid_area[3].set(681, 22, 0, 3);
valid_area[4].set(942, 105, 0, 4);
valid_area[5].set(1000, 360, 0, 5);
valid_area[6].set(1000, 1000, 0, 6);
valid_area[7].set(0, 1000, 0, 7);
std::vector<double> err_records;
std::vector<vertex2dc*> tin_vert;
std::vector<triangle*> tin_ele;
rnd2tin(topo, tin_vert, tin_ele, 1.0, &valid_area, &err_records);
// Write a log file
std::ofstream logfile("data/topo_rnd_TIN2.log");
logfile << "# Insertion Maxi-Error\n";
for (int i = 0; i < err_records.size(); ++i)
{
logfile << i+1 << " " << err_records[i] << std::endl;
}
logfile.close();
// Write a Gmsh's .msh file
std::ofstream outfile("data/topo_rnd_TIN2.msh");
outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<<std::endl;
outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16)
<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
}
outfile<<"$EndNodes"<<std::endl;
outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1 << " 2 0";
for (int j = 0; j < 3; j++)
{
outfile << " " << tin_ele[i]->vert[j]->id + 1;
}
outfile << std::endl;
}
outfile << "$EndElements"<< std::endl;
outfile<<"$NodeData"<<std::endl;
outfile<<1<<std::endl
<<"\"Topography (m)\"" <<std::endl
<< 1 <<std::endl<< 0.0 <<std::endl
<< 3 <<std::endl<< 0<<std::endl
<< 1 <<std::endl<< tin_vert.size() <<std::endl;
for (int i = 0; i < tin_vert.size(); i++)
{
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl;
}
outfile << "$EndNodeData" << std::endl;
outfile.close();
// write a neighbor file
outfile.open("data/topo_rnd_TIN2.neigh");
outfile << tin_ele.size() << std::endl;
for (int i = 0; i < tin_ele.size(); i++)
{
outfile << i + 1;
for (int j = 0; j < 3; j++)
{
if (tin_ele[i]->neigh[j] != nullptr)
{
outfile << " " << tin_ele[i]->neigh[j]->id + 1;
}
else outfile << " -1";
}
outfile << std::endl;
}
outfile.close();
// Destroy memories allocated by the dem2tin function
for (int i = 0; i < tin_vert.size(); ++i)
{
delete tin_vert[i];
}
for (int i = 0; i < tin_ele.size(); ++i)
{
delete tin_ele[i];
}
return 0;
}

View File

@ -156,7 +156,7 @@ double triangle::interpolate(double inx, double iny)
* / \ * / \
* / \ * / \
* / t \ * / t \
* t_id-------\ t_id (0, 1 or 2) * t_id-------\ t_id+1 (0, 1 or 2)
* \--------/ * \--------/
* \ / * \ /
* \ n / * \ n /
@ -294,7 +294,9 @@ void make_delaunay(triangle *t)
dist = (t->cx - n_vert->x) * (t->cx - n_vert->x) + dist = (t->cx - n_vert->x) * (t->cx - n_vert->x) +
(t->cy - n_vert->y) * (t->cy - n_vert->y); (t->cy - n_vert->y) * (t->cy - n_vert->y);
if ((dist - t->cr) < -1.0*ZERO) // A very restrict condition. The testing point must be really inside the circumcircle // We have to use a very restrict condition here. The testing point must be really inside the circumcircle.
// Otherwise, this recursive function may fall into endless callings till the segment fails.
if ((dist - t->cr) < -1.0*ZERO)
{ {
flip_neighboring_triangles(t, n_tri, n, v); flip_neighboring_triangles(t, n_tri, n, v);
@ -429,6 +431,74 @@ triangle *split_triangle(vertex2dc *v, triangle *t, triangle *new_t[4])
} }
// End triangle definition // End triangle definition
/**
* @brief Test if the input triangle is inside of the given polygon
*
* @param tri_p Pointer of a test triangle
* @param poly_vert Vertexes of a polygon
* @return true The test triangle is inside of the polygon
* @return false The test triangle is outside of the polygon
*/
bool triangle_inside_polygon(triangle *tri_p, std::vector<vertex2dc> *poly_vert)
{
// If any vertexes of the input triangle is outside of the polygon, return false. Otherwise, return true
if (poly_vert->size() < 3)
{
return false;
}
else
{
int pnum = poly_vert->size();
//确定外接矩形
double xmin = poly_vert->at(0).x, ymin = poly_vert->at(0).y;
double xmax = poly_vert->at(0).x, ymax = poly_vert->at(0).y;
for (int j = 0; j < pnum; ++j)
{
xmin = std::min(xmin, poly_vert->at(j).x);
xmax = std::max(xmax, poly_vert->at(j).x);
ymin = std::min(ymin, poly_vert->at(j).y);
ymax = std::max(ymax, poly_vert->at(j).y);
}
int count;
double tmp_x;
vertex2dc *one_p;
for (int t = 0; t < 3; ++t)
{
one_p = tri_p->vert[t];
// the testing point is outside of the surrounding box, return false
if (one_p->x < xmin || one_p->x > xmax || one_p->y < ymin || one_p->y > ymax)
{
return false;
}
else
{
count = 0;
for (int i = 0; i < pnum; ++i)
{
if ((one_p->y >= poly_vert->at(i).y && one_p->y < poly_vert->at((i+1)%pnum).y) ||
(one_p->y <= poly_vert->at(i).y && one_p->y > poly_vert->at((i+1)%pnum).y))
{
tmp_x = (poly_vert->at((i+1)%pnum).x - poly_vert->at(i).x)
* (one_p->y - poly_vert->at(i).y)/(poly_vert->at((i+1)%pnum).y - poly_vert->at(i).y)
+ poly_vert->at(i).x;
if (one_p->x <= tmp_x)
count++;
}
}
if (pow(-1, count) > 0) return false;
}
}
// all vertexes are inside the polygon
return true;
}
}
/** /**
* @brief Generate the TIN from the DEM grid * @brief Generate the TIN from the DEM grid
* *
@ -445,7 +515,8 @@ triangle *split_triangle(vertex2dc *v, triangle *t, triangle *new_t[4])
* @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex. * @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex.
*/ */
void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ymin, double ymax, double dx, void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ymin, double ymax, double dx,
double dy, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris, double maxi_err, std::vector<double> *err_records) double dy, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris, double maxi_err,
std::vector<vertex2dc> *outline_poly, std::vector<double> *err_records)
{ {
if (!out_verts.empty()) out_verts.clear(); if (!out_verts.empty()) out_verts.clear();
if (!out_tris.empty()) out_tris.clear(); if (!out_tris.empty()) out_tris.clear();
@ -461,7 +532,7 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
// Prepare the DEM points // Prepare the DEM points
dem_point *tmp_dem = nullptr; dem_point *tmp_dem = nullptr;
std::vector<dem_point*> dem_tri; dem_point *maxi_err_dem = nullptr;
std::vector<dem_point*>::iterator d_iter; std::vector<dem_point*>::iterator d_iter;
vertex2dc *tmp_vert = nullptr; vertex2dc *tmp_vert = nullptr;
@ -522,28 +593,30 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
} }
} }
// Sort hosted_dem in the desceding order with respect to the error. Add maximal zeros to dem_tri // Sort hosted_dem in the desceding order with respect to the error. Get pointer of the dem_point with maximal error
double maxi_err_tmp = -1.0;
for (int t = 0; t < out_tris.size(); ++t) for (int t = 0; t < out_tris.size(); ++t)
{ {
std::sort(out_tris[t]->hosted_dem.begin(), out_tris[t]->hosted_dem.end(), compare_dem_point); std::sort(out_tris[t]->hosted_dem.begin(), out_tris[t]->hosted_dem.end(), compare_dem_point);
dem_tri.push_back(out_tris[t]->hosted_dem[0]); if (out_tris[t]->hosted_dem[0]->err > maxi_err_tmp)
{
maxi_err_tmp = out_tris[t]->hosted_dem[0]->err;
maxi_err_dem = out_tris[t]->hosted_dem[0];
}
} }
// Sort dem_tri while (maxi_err_dem->err >= maxi_err) // quit til the threshold is meet
std::sort(dem_tri.begin(), dem_tri.end(), compare_dem_point);
while (dem_tri[0]->err >= maxi_err) // quit til the threshold is meet
{ {
if (err_records != nullptr) if (err_records != nullptr)
{ {
err_records->push_back(dem_tri[0]->err); err_records->push_back(maxi_err_dem->err);
} }
// find the triangle that includes dem_tri[0] and remove it from out_tris // find the triangle that includes maxi_err_dem and remove it from out_tris
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); ) for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{ {
old_tri = *t_iter; old_tri = *t_iter;
if (old_tri == dem_tri[0]->host) if (old_tri == maxi_err_dem->host)
{ {
t_iter = out_tris.erase(t_iter); t_iter = out_tris.erase(t_iter);
break; break;
@ -551,10 +624,10 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
else t_iter++; else t_iter++;
} }
// remove dem_tri[0] from its host triangle's hosted DEM list // remove maxi_err_dem from its host triangle's hosted DEM list
for (d_iter = old_tri->hosted_dem.begin(); d_iter != old_tri->hosted_dem.end(); ) for (d_iter = old_tri->hosted_dem.begin(); d_iter != old_tri->hosted_dem.end(); )
{ {
if (dem_tri[0] == *d_iter) if (maxi_err_dem == *d_iter)
{ {
d_iter = old_tri->hosted_dem.erase(d_iter); d_iter = old_tri->hosted_dem.erase(d_iter);
break; break;
@ -563,11 +636,11 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
} }
// create a new vertex // create a new vertex
tmp_vert = new vertex2dc(dem_tri[0]->x, dem_tri[0]->y, dem_tri[0]->elev, out_verts.size()); tmp_vert = new vertex2dc(maxi_err_dem->x, maxi_err_dem->y, maxi_err_dem->elev, out_verts.size());
out_verts.push_back(tmp_vert); out_verts.push_back(tmp_vert);
// Delete dem_tri[0] // Delete maxi_err_dem
tmp_dem = dem_tri[0]; delete tmp_dem; delete maxi_err_dem; maxi_err_dem = nullptr;
// build new triangles // build new triangles
tmp_tri = split_triangle(tmp_vert, old_tri, cnst_tri); tmp_tri = split_triangle(tmp_vert, old_tri, cnst_tri);
@ -677,22 +750,52 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
} }
} }
// get maximal errors from out_tris and sort dem_tri // get maximal errors from out_tris
dem_tri.clear(); dem_tri.reserve(out_tris.size()); maxi_err_tmp = -1.0;
for (int t = 0; t < out_tris.size(); t++) for (int t = 0; t < out_tris.size(); t++)
{ {
if (!out_tris[t]->hosted_dem.empty()) if (!out_tris[t]->hosted_dem.empty() && out_tris[t]->hosted_dem[0]->err > maxi_err_tmp)
{ {
dem_tri.push_back(out_tris[t]->hosted_dem[0]); maxi_err_tmp = out_tris[t]->hosted_dem[0]->err;
maxi_err_dem = out_tris[t]->hosted_dem[0];
} }
} }
std::sort(dem_tri.begin(), dem_tri.end(), compare_dem_point);
} }
if (err_records != nullptr) if (err_records != nullptr)
{ {
err_records->push_back(dem_tri[0]->err); err_records->push_back(maxi_err_dem->err);
}
// Cut outline if there is one
if (outline_poly != nullptr)
{
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{
tmp_tri = *t_iter;
if (!triangle_inside_polygon(tmp_tri, outline_poly))
{
// set neighbors
for (int i = 0; i < 3; ++i)
{
if (tmp_tri->neigh[i] != nullptr)
{
for (int j = 0; j < 3; ++j)
{
if (tmp_tri->neigh[i]->neigh[j] == tmp_tri)
{
tmp_tri->neigh[i]->neigh[j] = nullptr;
break;
}
}
}
}
// destroy the memories located and remove from the vector
t_iter = out_tris.erase(t_iter);
delete tmp_tri; tmp_tri = nullptr;
}
else t_iter++;
}
} }
// assign triangles index // assign triangles index
@ -709,6 +812,7 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
return; return;
} }
/** /**
* @brief Generate the TIN from random DEM points * @brief Generate the TIN from random DEM points
* *
@ -716,11 +820,370 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
* @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0 * @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0
* @param[in] outline_poly If this pointer is not NULL, Cut triangle outside the polygon. * @param[in] outline_poly If this pointer is not NULL, Cut triangle outside of or intersected with the polygon.
* @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex. * @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex.
*/ */
void rnd2tin(const std::vector<dem_point> &dem, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris, void rnd2tin(const std::vector<dem_point> &dem, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris,
double maxi_err, std::vector<dem_point> *outline_poly, std::vector<double> *err_records) double maxi_err, std::vector<vertex2dc> *outline_poly, std::vector<double> *err_records)
{ {
if (dem.size() < 3) return;
if (maxi_err <= 0.0) return;
if (!out_verts.empty()) out_verts.clear();
if (!out_tris.empty()) out_tris.clear();
if (err_records != nullptr && !err_records->empty()) err_records->clear();
// locate the surrounding box and initiate the staring two triangles
double xmin = dem[0].x, xmax = dem[0].x;
double ymin = dem[0].y, ymax = dem[0].y;
for (int i = 0; i < dem.size(); ++i)
{
xmin = std::min(xmin, dem[i].x);
xmax = std::max(xmax, dem[i].x);
ymin = std::min(ymin, dem[i].y);
ymax = std::max(ymax, dem[i].y);
}
double midx = 0.5*(xmin + xmax);
double midy = 0.5*(ymin + ymax);
double maxi_s = std::max(xmax - xmin, ymax - ymin); // use an four times bigger rectangle to include all points
vertex2dc *tmp_vert = nullptr;
std::vector<vertex2dc*> box_vert;
tmp_vert = new vertex2dc(midx - maxi_s, midy - maxi_s, 0.0, 0); // lower left corner
box_vert.push_back(tmp_vert);
tmp_vert = new vertex2dc(midx + maxi_s, midy - maxi_s, 0.0, 1); // lower right corner
box_vert.push_back(tmp_vert);
tmp_vert = new vertex2dc(midx + maxi_s, midy + maxi_s, 0.0, 2); // upper right corner
box_vert.push_back(tmp_vert);
tmp_vert = new vertex2dc(midx - maxi_s, midy + maxi_s, 0.0, 3); // upper left corner
box_vert.push_back(tmp_vert);
triangle *old_tri = nullptr, *tmp_tri = nullptr;
triangle *cnst_tri[4];
std::vector<triangle*>::iterator t_iter;
if (!is_collinear(box_vert[0], box_vert[1], box_vert[2])) // Do not create triangle if the vertexes are collinear
{
tmp_tri = new triangle(box_vert[0], box_vert[1], box_vert[2]); // order the vertex anti-clock wise
out_tris.push_back(tmp_tri); tmp_tri = nullptr;
}
if (!is_collinear(box_vert[0], box_vert[2], box_vert[3]))
{
tmp_tri = new triangle(box_vert[0], box_vert[2], box_vert[3]); // order the vertex anti-clock wise
out_tris.push_back(tmp_tri); tmp_tri = nullptr;
}
if (out_tris.size() != 2) return;
out_tris[0]->set_neighbor(nullptr, nullptr, out_tris[1]);
out_tris[1]->set_neighbor(out_tris[0], nullptr, nullptr);
// Prepare the DEM points
dem_point *tmp_dem = nullptr;
dem_point *maxi_err_dem = nullptr;
std::vector<dem_point*>::iterator d_iter;
// Find host triangle for all DEM locations
for (int d = 0; d < dem.size(); ++d)
{
tmp_dem = new dem_point(dem[d].x, dem[d].y, dem[d].elev);
for (int t = 0; t < out_tris.size(); ++t)
{
if (out_tris[t]->bound_location(tmp_dem->x, tmp_dem->y))
{
tmp_dem->host = out_tris[t];
tmp_dem->err = fabs(out_tris[t]->interpolate(tmp_dem->x, tmp_dem->y) - tmp_dem->elev);
out_tris[t]->hosted_dem.push_back(tmp_dem);
break; // already found, no need to search more
}
}
}
// Sort hosted_dem in the desceding order with respect to the error. Get pointer of the dem_point with maximal error
double maxi_err_tmp = -1.0;
for (int t = 0; t < out_tris.size(); ++t)
{
std::sort(out_tris[t]->hosted_dem.begin(), out_tris[t]->hosted_dem.end(), compare_dem_point);
if (out_tris[t]->hosted_dem[0]->err > maxi_err_tmp)
{
maxi_err_tmp = out_tris[t]->hosted_dem[0]->err;
maxi_err_dem = out_tris[t]->hosted_dem[0];
}
}
while (maxi_err_dem->err >= maxi_err) // quit til the threshold is meet
{
if (err_records != nullptr)
{
err_records->push_back(maxi_err_dem->err);
}
// find the triangle that includes maxi_err_dem and remove it from out_tris
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{
old_tri = *t_iter;
if (old_tri == maxi_err_dem->host)
{
t_iter = out_tris.erase(t_iter);
break;
}
else t_iter++;
}
// remove maxi_err_dem from its host triangle's hosted DEM list
for (d_iter = old_tri->hosted_dem.begin(); d_iter != old_tri->hosted_dem.end(); )
{
if (maxi_err_dem == *d_iter)
{
d_iter = old_tri->hosted_dem.erase(d_iter);
break;
}
else d_iter++;
}
// create a new vertex
tmp_vert = new vertex2dc(maxi_err_dem->x, maxi_err_dem->y, maxi_err_dem->elev, out_verts.size());
out_verts.push_back(tmp_vert);
// Delete maxi_err_dem
delete maxi_err_dem; maxi_err_dem = nullptr;
// build new triangles
tmp_tri = split_triangle(tmp_vert, old_tri, cnst_tri);
for (int n = 0; n < 4; ++n)
{
if (cnst_tri[n] != nullptr)
{
out_tris.push_back(cnst_tri[n]);
}
}
if (tmp_tri != nullptr)
{
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{
if (tmp_tri == *t_iter)
{
t_iter = out_tris.erase(t_iter);
break;
}
else t_iter++;
}
// build hosted dem for the new triangles
for (int d = 0; d < old_tri->hosted_dem.size(); d++)
{
tmp_dem = old_tri->hosted_dem[d];
for (int n = 0; n < 4; n++)
{
if (cnst_tri[n] != nullptr && cnst_tri[n]->bound_location(tmp_dem->x, tmp_dem->y))
{
tmp_dem->host = cnst_tri[n];
tmp_dem->err = fabs(cnst_tri[n]->interpolate(tmp_dem->x, tmp_dem->y) - tmp_dem->elev);
cnst_tri[n]->hosted_dem.push_back(tmp_dem);
break;
}
}
}
for (int d = 0; d < tmp_tri->hosted_dem.size(); d++)
{
tmp_dem = tmp_tri->hosted_dem[d];
for (int n = 0; n < 4; n++)
{
if (cnst_tri[n] != nullptr && cnst_tri[n]->bound_location(tmp_dem->x, tmp_dem->y))
{
tmp_dem->host = cnst_tri[n];
tmp_dem->err = fabs(cnst_tri[n]->interpolate(tmp_dem->x, tmp_dem->y) - tmp_dem->elev);
cnst_tri[n]->hosted_dem.push_back(tmp_dem);
break;
}
}
}
for (int n = 0; n < 4; n++)
{
if (cnst_tri[n] != nullptr)
{
std::sort(cnst_tri[n]->hosted_dem.begin(), cnst_tri[n]->hosted_dem.end(), compare_dem_point);
}
}
// delete the old triangle
old_tri->hosted_dem.clear();
delete old_tri; old_tri = nullptr;
tmp_tri->hosted_dem.clear();
delete tmp_tri; tmp_tri = nullptr;
}
else
{
// build hosted dem for the new triangles
for (int d = 0; d < old_tri->hosted_dem.size(); d++)
{
tmp_dem = old_tri->hosted_dem[d];
for (int n = 0; n < 4; n++)
{
if (cnst_tri[n] != nullptr && cnst_tri[n]->bound_location(tmp_dem->x, tmp_dem->y))
{
tmp_dem->host = cnst_tri[n];
tmp_dem->err = fabs(cnst_tri[n]->interpolate(tmp_dem->x, tmp_dem->y) - tmp_dem->elev);
cnst_tri[n]->hosted_dem.push_back(tmp_dem);
break;
}
}
}
for (int n = 0; n < 4; n++)
{
if (cnst_tri[n] != nullptr)
{
std::sort(cnst_tri[n]->hosted_dem.begin(), cnst_tri[n]->hosted_dem.end(), compare_dem_point);
}
}
// delete the old triangle
old_tri->hosted_dem.clear();
delete old_tri; old_tri = nullptr;
}
// Make sure cnst_tri meet the empty circumcircle condition
for (int n = 0; n < 4; ++n)
{
if (cnst_tri[n] != nullptr)
{
make_delaunay(cnst_tri[n]);
}
}
// get maximal errors from out_tris
maxi_err_tmp = -1.0;
for (int t = 0; t < out_tris.size(); t++)
{
if (!out_tris[t]->hosted_dem.empty() && out_tris[t]->hosted_dem[0]->err > maxi_err_tmp)
{
maxi_err_tmp = out_tris[t]->hosted_dem[0]->err;
maxi_err_dem = out_tris[t]->hosted_dem[0];
}
}
}
if (err_records != nullptr)
{
err_records->push_back(maxi_err_dem->err);
}
// remove any triangles has an box vertex from out_tris
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{
tmp_tri = *t_iter;
if (tmp_tri->vert[0] == box_vert[0] || tmp_tri->vert[0] == box_vert[1] || tmp_tri->vert[0] == box_vert[2] || tmp_tri->vert[0] == box_vert[3])
{
if (tmp_tri->neigh[1] != nullptr)
{
for (int k = 0; k < 3; ++k)
{
if (tmp_tri->neigh[1]->neigh[k] == tmp_tri)
{
tmp_tri->neigh[1]->neigh[k] = nullptr;
break;
}
}
}
// destroy the memories located and remove from the vector
t_iter = out_tris.erase(t_iter);
delete tmp_tri; tmp_tri = nullptr;
}
else if (tmp_tri->vert[1] == box_vert[0] || tmp_tri->vert[1] == box_vert[1] || tmp_tri->vert[1] == box_vert[2] || tmp_tri->vert[1] == box_vert[3])
{
if (tmp_tri->neigh[2] != nullptr)
{
for (int k = 0; k < 3; ++k)
{
if (tmp_tri->neigh[2]->neigh[k] == tmp_tri)
{
tmp_tri->neigh[2]->neigh[k] = nullptr;
break;
}
}
}
// destroy the memories located and remove from the vector
t_iter = out_tris.erase(t_iter);
delete tmp_tri; tmp_tri = nullptr;
}
else if (tmp_tri->vert[2] == box_vert[0] || tmp_tri->vert[2] == box_vert[1] || tmp_tri->vert[2] == box_vert[2] || tmp_tri->vert[2] == box_vert[3])
{
if (tmp_tri->neigh[0] != nullptr)
{
for (int k = 0; k < 3; ++k)
{
if (tmp_tri->neigh[0]->neigh[k] == tmp_tri)
{
tmp_tri->neigh[0]->neigh[k] = nullptr;
break;
}
}
}
// destroy the memories located and remove from the vector
t_iter = out_tris.erase(t_iter);
delete tmp_tri; tmp_tri = nullptr;
}
else t_iter++;
}
// Cut outline if there is one
if (outline_poly != nullptr)
{
for (t_iter = out_tris.begin(); t_iter != out_tris.end(); )
{
tmp_tri = *t_iter;
if (!triangle_inside_polygon(tmp_tri, outline_poly))
{
// set neighbors
for (int i = 0; i < 3; ++i)
{
if (tmp_tri->neigh[i] != nullptr)
{
for (int j = 0; j < 3; ++j)
{
if (tmp_tri->neigh[i]->neigh[j] == tmp_tri)
{
tmp_tri->neigh[i]->neigh[j] = nullptr;
break;
}
}
}
}
// destroy the memories located and remove from the vector
t_iter = out_tris.erase(t_iter);
delete tmp_tri; tmp_tri = nullptr;
}
else t_iter++;
}
}
// assign triangles index
for (int i = 0; i < out_tris.size(); i++)
{
out_tris[i]->id = i;
// destroy remaining DEM data
for (int d = 0; d < out_tris[i]->hosted_dem.size(); d++)
{
tmp_dem = out_tris[i]->hosted_dem[d];
delete tmp_dem; tmp_dem = nullptr;
}
}
// destroy memories located for box_vert
for (int i = 0; i < 4; ++i)
{
delete box_vert[i]; box_vert[i] = nullptr;
}
return; return;
} }

View File

@ -51,7 +51,7 @@ struct vertex2dc
}; };
/** /**
* @brief Compare two vertexes * @brief Compare two vertexes. Index of the vertexes are not used for comparsion
* *
* @param a vertex a * @param a vertex a
* @param b vertex b * @param b vertex b
@ -92,7 +92,7 @@ struct dem_point
double x, y; // position of the DEM location double x, y; // position of the DEM location
double elev; // elevation at the DEM location double elev; // elevation at the DEM location
double err; // error of the TIN with respect to the elevation double err; // error of the TIN with respect to the elevation
triangle *host; triangle *host; // pointer of the triangle that the dem_point falls inside of
dem_point(); dem_point();
@ -185,7 +185,17 @@ struct triangle
// End triangle definition // End triangle definition
/** /**
* @brief Generate the TIN from the DEM grid * @brief Test if the input triangle is inside of the given polygon
*
* @param tri_p Pointer of a test triangle
* @param poly_vert Vertexes of a polygon
* @return true The test triangle is inside of the polygon
* @return false The test triangle is outside of the polygon
*/
bool triangle_inside_polygon(triangle *tri_p, std::vector<vertex2dc> *poly_vert);
/**
* @brief Generate the TIN from a dense DEM grid
* *
* @param[in] dem Input DEM grid (Ordered from lower left corner to the upper right corner) * @param[in] dem Input DEM grid (Ordered from lower left corner to the upper right corner)
* @param[in] xmin The minimal coordinate of the DEM grid on the x-axis * @param[in] xmin The minimal coordinate of the DEM grid on the x-axis
@ -197,11 +207,12 @@ struct triangle
* @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0 * @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0
* @param[in] outline_poly If this pointer is not NULL, Cut triangle outside of or intersected with the polygon.
* @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex. * @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex.
*/ */
void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ymin, double ymax, void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ymin, double ymax,
double dx, double dy, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris, double dx, double dy, std::vector<vertex2dc*> &out_verts, std::vector<triangle*> &out_tris,
double maxi_err = 1e-0, std::vector<double> *err_records = nullptr); double maxi_err = 1e-0, std::vector<vertex2dc> *outline_poly = nullptr, std::vector<double> *err_records = nullptr);
/** /**
* @brief Generate the TIN from random DEM points * @brief Generate the TIN from random DEM points
@ -210,11 +221,11 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
* @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_verts The output vector of vertex's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector * @param out_tris The output vector of triangle's pointers. The user need to destroy the memories allocated by the function before destroy the vector
* @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0 * @param[in] maxi_err Threshold to quit the algorithm. The default is 1e-0
* @param[in] outline_poly If this pointer is not NULL, Cut triangle outside the polygon. * @param[in] outline_poly If this pointer is not NULL, Cut triangle outside of or intersected with the polygon.
* @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex. * @param[in] err_records If this pointer is not NULL, record maximal error values after each insertion of vertex.
*/ */
void rnd2tin(const std::vector<dem_point> &dem, std::vector<vertex2dc*> &out_verts, void rnd2tin(const std::vector<dem_point> &dem, std::vector<vertex2dc*> &out_verts,
std::vector<triangle*> &out_tris, double maxi_err = 1e-0, std::vector<dem_point> *outline_poly = nullptr, std::vector<triangle*> &out_tris, double maxi_err = 1e-0, std::vector<vertex2dc> *outline_poly = nullptr,
std::vector<double> *err_records = nullptr); std::vector<double> *err_records = nullptr);
#endif // _TIN_DELAUNAY_H #endif // _TIN_DELAUNAY_H