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

View File

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

View File

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

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()
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<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
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_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,6 +812,7 @@ void dem2tin(const std::vector<double> &dem, double xmin, double xmax, double ym
return;
}
/**
* @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_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;
}

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 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,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_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
@ -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_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