tmp update
This commit is contained in:
parent
e3812057b7
commit
10bb022a07
@ -1975,8 +1975,8 @@
|
||||
1974 1.4206
|
||||
1975 1.1363
|
||||
1976 1.136
|
||||
1977 1.136
|
||||
1978 1.4285
|
||||
1977 1.4285
|
||||
1978 1.136
|
||||
1979 1.1355
|
||||
1980 1.1352
|
||||
1981 1.69885
|
||||
@ -2075,8 +2075,8 @@
|
||||
2074 1.49957
|
||||
2075 1.07982
|
||||
2076 1.0787
|
||||
2077 1.29195
|
||||
2078 1.0787
|
||||
2077 1.0787
|
||||
2078 1.29195
|
||||
2079 1.07857
|
||||
2080 1.72454
|
||||
2081 1.0785
|
||||
|
@ -1982,9 +1982,9 @@ $Nodes
|
||||
1977 350 750 84.5986
|
||||
1978 330 750 89.6465
|
||||
1979 240 570 45.0428
|
||||
1980 700 420 115.744
|
||||
1981 520 470 168.821
|
||||
1982 510 470 168.277
|
||||
1980 520 470 168.821
|
||||
1981 510 470 168.277
|
||||
1982 700 420 115.744
|
||||
1983 260 800 53.4204
|
||||
1984 910 280 26.9883
|
||||
1985 900 260 26.7625
|
||||
@ -2082,9 +2082,9 @@ $Nodes
|
||||
2077 620 20 12.1613
|
||||
2078 600 40 16.9786
|
||||
2079 890 80 19.6648
|
||||
2080 880 300 34.2451
|
||||
2081 900 300 29.6101
|
||||
2082 480 760 36.4966
|
||||
2080 480 760 36.4966
|
||||
2081 880 300 34.2451
|
||||
2082 900 300 29.6101
|
||||
2083 690 240 61.8001
|
||||
2084 700 220 52.8594
|
||||
2085 730 620 29.0292
|
||||
@ -2532,7 +2532,7 @@ $Elements
|
||||
273 2 0 412 513 1200
|
||||
274 2 0 413 513 412
|
||||
275 2 0 561 514 75
|
||||
276 2 0 47 1982 528
|
||||
276 2 0 47 1981 528
|
||||
277 2 0 220 753 515
|
||||
278 2 0 410 810 260
|
||||
279 2 0 748 516 148
|
||||
@ -2801,7 +2801,7 @@ $Elements
|
||||
542 2 0 700 701 55
|
||||
543 2 0 1084 314 1197
|
||||
544 2 0 231 703 493
|
||||
545 2 0 1980 704 1040
|
||||
545 2 0 1982 704 1040
|
||||
546 2 0 243 704 284
|
||||
547 2 0 596 425 705
|
||||
548 2 0 636 52 706
|
||||
@ -3650,7 +3650,7 @@ $Elements
|
||||
1391 2 0 2186 1154 201
|
||||
1392 2 0 391 1245 1408
|
||||
1393 2 0 391 1408 392
|
||||
1394 2 0 527 1982 1155
|
||||
1394 2 0 527 1981 1155
|
||||
1395 2 0 434 527 1155
|
||||
1396 2 0 539 887 1156
|
||||
1397 2 0 10 1138 1157
|
||||
@ -3684,7 +3684,7 @@ $Elements
|
||||
1425 2 0 952 951 1168
|
||||
1426 2 0 124 1148 1168
|
||||
1427 2 0 1917 1169 201
|
||||
1428 2 0 2082 2008 1354
|
||||
1428 2 0 2080 2008 1354
|
||||
1429 2 0 916 1170 154
|
||||
1430 2 0 64 1461 916
|
||||
1431 2 0 1038 192 1171
|
||||
@ -5202,7 +5202,7 @@ $Elements
|
||||
2943 2 0 1372 1760 1595
|
||||
2944 2 0 286 1760 1371
|
||||
2945 2 0 1817 1760 286
|
||||
2946 2 0 1980 1761 536
|
||||
2946 2 0 1982 1761 536
|
||||
2947 2 0 2029 1761 1039
|
||||
2948 2 0 1214 1761 1040
|
||||
2949 2 0 817 1761 1214
|
||||
@ -5835,15 +5835,15 @@ $Elements
|
||||
3576 2 0 566 1979 898
|
||||
3577 2 0 1317 1979 228
|
||||
3578 2 0 898 1979 1317
|
||||
3579 2 0 284 704 1980
|
||||
3580 2 0 1040 1761 1980
|
||||
3581 2 0 536 284 1980
|
||||
3582 2 0 455 1981 47
|
||||
3583 2 0 456 1981 455
|
||||
3584 2 0 1981 1982 47
|
||||
3585 2 0 528 1982 527
|
||||
3586 2 0 456 1982 1981
|
||||
3587 2 0 1155 1982 456
|
||||
3579 2 0 455 1980 47
|
||||
3580 2 0 456 1980 455
|
||||
3581 2 0 1980 1981 47
|
||||
3582 2 0 528 1981 527
|
||||
3583 2 0 456 1981 1980
|
||||
3584 2 0 1155 1981 456
|
||||
3585 2 0 284 704 1982
|
||||
3586 2 0 1040 1761 1982
|
||||
3587 2 0 536 284 1982
|
||||
3588 2 0 381 1605 1983
|
||||
3589 2 0 1374 1375 1983
|
||||
3590 2 0 1375 1876 1983
|
||||
@ -5986,7 +5986,7 @@ $Elements
|
||||
3727 2 0 1505 2027 649
|
||||
3728 2 0 2237 2027 1477
|
||||
3729 2 0 386 2027 1505
|
||||
3730 2 0 2080 2027 386
|
||||
3730 2 0 2081 2027 386
|
||||
3731 2 0 112 2028 1324
|
||||
3732 2 0 1324 2028 467
|
||||
3733 2 0 780 2028 112
|
||||
@ -6147,17 +6147,17 @@ $Elements
|
||||
3888 2 0 1234 2079 1221
|
||||
3889 2 0 1220 2079 712
|
||||
3890 2 0 1221 2079 1773
|
||||
3891 2 0 2027 2080 1477
|
||||
3892 2 0 1477 2080 830
|
||||
3893 2 0 1984 2081 386
|
||||
3894 2 0 830 2080 627
|
||||
3895 2 0 1941 2081 1984
|
||||
3896 2 0 386 2081 2080
|
||||
3897 2 0 627 2081 1941
|
||||
3898 2 0 2080 2081 627
|
||||
3899 2 0 1143 417 2082
|
||||
3900 2 0 417 2008 2082
|
||||
3901 2 0 1354 1143 2082
|
||||
3891 2 0 1143 417 2080
|
||||
3892 2 0 417 2008 2080
|
||||
3893 2 0 1354 1143 2080
|
||||
3894 2 0 2027 2081 1477
|
||||
3895 2 0 1477 2081 830
|
||||
3896 2 0 1984 2082 386
|
||||
3897 2 0 830 2081 627
|
||||
3898 2 0 1941 2082 1984
|
||||
3899 2 0 386 2082 2081
|
||||
3900 2 0 627 2082 1941
|
||||
3901 2 0 2081 2082 627
|
||||
3902 2 0 253 1693 2083
|
||||
3903 2 0 769 253 2083
|
||||
3904 2 0 770 1801 2084
|
||||
@ -8693,9 +8693,9 @@ $NodeData
|
||||
1977 84.5986
|
||||
1978 89.6465
|
||||
1979 45.0428
|
||||
1980 115.744
|
||||
1981 168.821
|
||||
1982 168.277
|
||||
1980 168.821
|
||||
1981 168.277
|
||||
1982 115.744
|
||||
1983 53.4204
|
||||
1984 26.9883
|
||||
1985 26.7625
|
||||
@ -8793,9 +8793,9 @@ $NodeData
|
||||
2077 12.1613
|
||||
2078 16.9786
|
||||
2079 19.6648
|
||||
2080 34.2451
|
||||
2081 29.6101
|
||||
2082 36.4966
|
||||
2080 36.4966
|
||||
2081 34.2451
|
||||
2082 29.6101
|
||||
2083 61.8001
|
||||
2084 52.8594
|
||||
2085 29.0292
|
||||
|
@ -199,7 +199,7 @@
|
||||
198 22 1023 197
|
||||
199 1985 483 3758
|
||||
200 510 511 201
|
||||
201 200 504 3582
|
||||
201 200 504 3579
|
||||
202 291 1395 175
|
||||
203 400 2249 205
|
||||
204 88 34 2248
|
||||
@ -274,7 +274,7 @@
|
||||
273 274 1498 2688
|
||||
274 773 273 152
|
||||
275 344 128 342
|
||||
276 3584 3585 292
|
||||
276 3581 3582 292
|
||||
277 622 624 396
|
||||
278 706 704 1929
|
||||
279 612 2848 610
|
||||
@ -288,10 +288,10 @@
|
||||
287 2709 418 2442
|
||||
288 1044 289 816
|
||||
289 1401 288 606
|
||||
290 249 1633 3587
|
||||
290 249 1633 3584
|
||||
291 64 293 202
|
||||
292 510 276 4446
|
||||
293 291 2469 3585
|
||||
293 291 2469 3582
|
||||
294 1051 901 478
|
||||
295 647 788 375
|
||||
296 930 297 456
|
||||
@ -543,8 +543,8 @@
|
||||
542 540 541 538
|
||||
543 1235 1490 3644
|
||||
544 2598 2813 781
|
||||
545 3579 1135 3580
|
||||
546 1099 3579 72
|
||||
545 3585 1135 3586
|
||||
546 1099 3585 72
|
||||
547 1507 386 996
|
||||
548 1883 446 447
|
||||
549 4288 2612 4289
|
||||
@ -597,7 +597,7 @@
|
||||
596 984 338 842
|
||||
597 850 598 72
|
||||
598 597 849 32
|
||||
599 848 850 3581
|
||||
599 848 850 3587
|
||||
600 602 601 216
|
||||
601 600 2625 3812
|
||||
602 2626 600 357
|
||||
@ -1259,7 +1259,7 @@
|
||||
1258 3833 4286 2277
|
||||
1259 2048 1362 4259
|
||||
1260 1261 2049 648
|
||||
1261 1362 1260 3899
|
||||
1261 1362 1260 3891
|
||||
1262 1264 1263 472
|
||||
1263 1262 1265 414
|
||||
1264 1265 1262 1194
|
||||
@ -1358,7 +1358,7 @@
|
||||
1357 1355 3322 365
|
||||
1358 1582 2287 2286
|
||||
1359 1153 1678 1676
|
||||
1360 1361 3901 155
|
||||
1360 1361 3893 155
|
||||
1361 1362 1360 2277
|
||||
1362 1261 1361 1259
|
||||
1363 2918 1364 430
|
||||
@ -1392,7 +1392,7 @@
|
||||
1391 2238 3399 4230
|
||||
1392 2416 2646 1393
|
||||
1393 1392 1971 2881
|
||||
1394 3585 3587 1395
|
||||
1394 3582 3584 1395
|
||||
1395 202 1394 177
|
||||
1396 1224 54 2140
|
||||
1397 1349 2184 1398
|
||||
@ -1426,7 +1426,7 @@
|
||||
1425 686 967 1424
|
||||
1426 1375 685 967
|
||||
1427 3400 3661 3399
|
||||
1428 3900 3662 3901
|
||||
1428 3892 3662 3893
|
||||
1429 1504 5 1403
|
||||
1430 2112 2114 897
|
||||
1431 1134 69 3468
|
||||
@ -2158,7 +2158,7 @@
|
||||
2157 2156 1743 3541
|
||||
2158 2159 2509 354
|
||||
2159 1743 2158 1741
|
||||
2160 3857 4415 3892
|
||||
2160 3857 4415 3895
|
||||
2161 2163 2162 3264
|
||||
2162 2161 2164 2662
|
||||
2163 102 2161 241
|
||||
@ -2498,7 +2498,7 @@
|
||||
2497 919 2495 2243
|
||||
2498 2500 2499 1003
|
||||
2499 2498 2501 353
|
||||
2500 2501 2498 3583
|
||||
2500 2501 2498 3580
|
||||
2501 2499 2500 502
|
||||
2502 458 2504 2400
|
||||
2503 2506 458 4280
|
||||
@ -2944,9 +2944,9 @@
|
||||
2943 3083 3101 2471
|
||||
2944 2945 3082 1872
|
||||
2945 3101 2944 3100
|
||||
2946 3580 3736 3581
|
||||
2946 3586 3736 3587
|
||||
2947 3736 497 3737
|
||||
2948 2949 3580 1530
|
||||
2948 2949 3586 1530
|
||||
2949 497 2948 1531
|
||||
2950 2952 1380 1006
|
||||
2951 1380 2953 1382
|
||||
@ -3463,7 +3463,7 @@
|
||||
3462 3461 3464 1208
|
||||
3463 3464 3461 3266
|
||||
3464 3462 3463 995
|
||||
3465 3853 3897 2080
|
||||
3465 3853 3900 2080
|
||||
3466 133 2080 3591
|
||||
3467 3469 3468 1436
|
||||
3468 3467 3470 1431
|
||||
@ -3577,23 +3577,23 @@
|
||||
3576 3575 3578 957
|
||||
3577 3578 643 2119
|
||||
3578 3576 3577 2320
|
||||
3579 546 545 3581
|
||||
3580 2948 2946 545
|
||||
3581 599 3579 2946
|
||||
3582 3583 3584 201
|
||||
3583 3586 3582 2500
|
||||
3584 3586 276 3582
|
||||
3585 276 1394 293
|
||||
3586 3587 3584 3583
|
||||
3587 1394 3586 290
|
||||
3579 3580 3581 201
|
||||
3580 3583 3579 2500
|
||||
3581 3583 276 3579
|
||||
3582 276 1394 293
|
||||
3583 3584 3581 3580
|
||||
3584 1394 3583 290
|
||||
3585 546 545 3587
|
||||
3586 2948 2946 545
|
||||
3587 599 3585 2946
|
||||
3588 4057 1878 3273
|
||||
3589 2741 3590 1878
|
||||
3590 3280 3273 3589
|
||||
3591 3895 3695 3466
|
||||
3591 3898 3695 3466
|
||||
3592 3594 3595 2236
|
||||
3593 3695 3595 3696
|
||||
3594 2004 3692 3592
|
||||
3595 3893 3592 3593
|
||||
3595 3896 3592 3593
|
||||
3596 3598 3597 1108
|
||||
3597 3596 3599 2835
|
||||
3598 1650 3596 1652
|
||||
@ -3661,7 +3661,7 @@
|
||||
3660 3658 3659 1582
|
||||
3661 1427 3662 3663
|
||||
3662 1832 1428 3661
|
||||
3663 799 3661 3900
|
||||
3663 799 3661 3892
|
||||
3664 3529 3863 3862
|
||||
3665 248 3666 3865
|
||||
3666 3207 3667 3665
|
||||
@ -3726,9 +3726,9 @@
|
||||
3725 2787 2786 2617
|
||||
3726 1096 4438 4439
|
||||
3727 3729 4402 2235
|
||||
3728 4402 3891 4403
|
||||
3728 4402 3894 4403
|
||||
3729 3730 3727 2236
|
||||
3730 3891 3729 3896
|
||||
3730 3894 3729 3899
|
||||
3731 3733 3732 4093
|
||||
3732 3731 3734 520
|
||||
3733 3734 3731 3683
|
||||
@ -3856,7 +3856,7 @@
|
||||
3855 3857 3856 2530
|
||||
3856 3855 2529 3854
|
||||
3857 3858 3855 2160
|
||||
3858 2529 3857 3894
|
||||
3858 2529 3857 3897
|
||||
3859 1657 4335 1389
|
||||
3860 3505 1658 4335
|
||||
3861 3007 1389 1658
|
||||
@ -3889,17 +3889,17 @@
|
||||
3888 3887 3890 3819
|
||||
3889 1538 1568 2770
|
||||
3890 3888 1538 2982
|
||||
3891 3730 3892 3728
|
||||
3892 3891 3894 2160
|
||||
3893 3895 3896 3595
|
||||
3894 3892 3898 3858
|
||||
3895 3897 3893 3591
|
||||
3896 3893 3898 3730
|
||||
3897 3898 3895 3465
|
||||
3898 3896 3897 3894
|
||||
3899 1261 3900 3901
|
||||
3900 3663 1428 3899
|
||||
3901 1360 3899 1428
|
||||
3891 1261 3892 3893
|
||||
3892 3663 1428 3891
|
||||
3893 1360 3891 1428
|
||||
3894 3730 3895 3728
|
||||
3895 3894 3897 2160
|
||||
3896 3898 3899 3595
|
||||
3897 3895 3901 3858
|
||||
3898 3900 3896 3591
|
||||
3899 3896 3901 3730
|
||||
3900 3901 3898 3465
|
||||
3901 3899 3900 3897
|
||||
3902 2747 2746 3903
|
||||
3903 3640 3902 1136
|
||||
3904 3202 3057 2768
|
||||
|
2249
data/topo_TIN2.log
Normal file
2249
data/topo_TIN2.log
Normal file
File diff suppressed because it is too large
Load Diff
8718
data/topo_TIN2.msh
Normal file
8718
data/topo_TIN2.msh
Normal file
File diff suppressed because it is too large
Load Diff
4198
data/topo_TIN2.neigh
Normal file
4198
data/topo_TIN2.neigh
Normal file
File diff suppressed because it is too large
Load Diff
8000
data/topo_rnd
Normal file
8000
data/topo_rnd
Normal file
File diff suppressed because it is too large
Load Diff
1439
data/topo_rnd_TIN.log
Normal file
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
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
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
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
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
2812
data/topo_rnd_TIN2.neigh
Normal file
File diff suppressed because it is too large
Load Diff
@ -66,3 +66,6 @@ macro(add_demo name)
|
||||
endmacro()
|
||||
|
||||
add_demo(demo)
|
||||
add_demo(demo2)
|
||||
add_demo(demo3)
|
||||
add_demo(demo4)
|
||||
|
@ -17,7 +17,7 @@ int main(int argc, char const *argv[])
|
||||
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, &err_records);
|
||||
dem2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records);
|
||||
|
||||
// Write a log file
|
||||
std::ofstream logfile("data/topo_TIN.log");
|
||||
|
94
src/demo/demo2.cpp
Normal file
94
src/demo/demo2.cpp
Normal 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
105
src/demo/demo3.cpp
Normal 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
105
src/demo/demo4.cpp
Normal 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;
|
||||
}
|
521
src/lib/tin.cpp
521
src/lib/tin.cpp
@ -156,7 +156,7 @@ double triangle::interpolate(double inx, double iny)
|
||||
* / \
|
||||
* / \
|
||||
* / t \
|
||||
* t_id-------\ t_id (0, 1 or 2)
|
||||
* t_id-------\ t_id+1 (0, 1 or 2)
|
||||
* \--------/
|
||||
* \ /
|
||||
* \ n /
|
||||
@ -294,7 +294,9 @@ void make_delaunay(triangle *t)
|
||||
dist = (t->cx - n_vert->x) * (t->cx - n_vert->x) +
|
||||
(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);
|
||||
|
||||
@ -429,6 +431,74 @@ triangle *split_triangle(vertex2dc *v, triangle *t, triangle *new_t[4])
|
||||
}
|
||||
// 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
|
||||
*
|
||||
@ -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.
|
||||
*/
|
||||
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_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
|
||||
dem_point *tmp_dem = nullptr;
|
||||
std::vector<dem_point*> dem_tri;
|
||||
dem_point *maxi_err_dem = nullptr;
|
||||
std::vector<dem_point*>::iterator d_iter;
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
std::sort(dem_tri.begin(), dem_tri.end(), compare_dem_point);
|
||||
|
||||
while (dem_tri[0]->err >= maxi_err) // quit til the threshold is meet
|
||||
while (maxi_err_dem->err >= maxi_err) // quit til the threshold is meet
|
||||
{
|
||||
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(); )
|
||||
{
|
||||
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);
|
||||
break;
|
||||
@ -551,10 +624,10 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
|
||||
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(); )
|
||||
{
|
||||
if (dem_tri[0] == *d_iter)
|
||||
if (maxi_err_dem == *d_iter)
|
||||
{
|
||||
d_iter = old_tri->hosted_dem.erase(d_iter);
|
||||
break;
|
||||
@ -563,11 +636,11 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Delete dem_tri[0]
|
||||
tmp_dem = dem_tri[0]; delete tmp_dem;
|
||||
// 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);
|
||||
@ -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
|
||||
dem_tri.clear(); dem_tri.reserve(out_tris.size());
|
||||
// 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())
|
||||
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)
|
||||
{
|
||||
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
|
||||
@ -709,18 +812,378 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate the TIN from random DEM points
|
||||
*
|
||||
* @param dem Input DEM points
|
||||
* @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 dem Input DEM points
|
||||
* @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[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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -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 b vertex b
|
||||
@ -92,7 +92,7 @@ struct dem_point
|
||||
double x, y; // position of the DEM location
|
||||
double elev; // elevation at the DEM location
|
||||
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();
|
||||
|
||||
@ -185,7 +185,17 @@ struct triangle
|
||||
// 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] xmin The minimal coordinate of the DEM grid on the x-axis
|
||||
@ -197,24 +207,25 @@ 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_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] 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.
|
||||
*/
|
||||
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 = 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
|
||||
*
|
||||
* @param dem Input DEM points
|
||||
* @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 dem Input DEM points
|
||||
* @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[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.
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif // _TIN_DELAUNAY_H
|
Loading…
Reference in New Issue
Block a user