213 lines
7.8 KiB
Markdown
213 lines
7.8 KiB
Markdown
### LibTIN - C++ library of the Triangular Irregular Network (TIN)
|
|
|
|
<img src="topo_TIN.png" alt="topo_TIN" style="zoom:24%;" />
|
|
|
|
#### Introduction
|
|
|
|
LibTIN is a stand alone C++ library for generating the Triangular Irregular Networks (TIN) using DEM data that are located at a regular grid or random locations. No dependences are needed. The generated TINs that are fully Delaunay, and neighboring information is also retrieved during the construction. Additionally, a polygon could be provided to control the outline shape of the generated TIN.
|
|
|
|
#### Installation
|
|
|
|
The LibTIN compiles using the CMake software. Typically, you need following commands to compile and install the library and tools after you navigated into the package's directory:
|
|
|
|
```shell
|
|
make build
|
|
cd build
|
|
cmake ..
|
|
make install
|
|
```
|
|
|
|
This will compile the library and two command line tools, _grd2tin_ and _rnd2tin_, which will be introduced bellow. The library and tools are installed in the directories _/usr/local/lib_ and _/usr/local/sbin_ by default. You can specify a different directory for installation using the CMAKE_INSTALL_PREFIX option.
|
|
|
|
#### Data Structures
|
|
|
|
##### vertex2dc
|
|
|
|
Vertex defined on the 2-D Cartesian coordinates. It is used to represent the vertex of the TIN or the polygon's corners. Included variables are as following:
|
|
|
|
```c++
|
|
struct vertex2dc
|
|
{
|
|
unsigned int id; // index of the vertex
|
|
double x, y; // position of the vertex
|
|
double elev; // elevation at the vertex
|
|
}
|
|
```
|
|
|
|
##### triangle
|
|
|
|
Triangular facet defined on the 2-D Cartesian coordinates. It is used to represent the facet of the TIN. Included variables are as following:
|
|
|
|
```c++
|
|
struct triangle
|
|
{
|
|
int id;
|
|
vertex2dc *vert[3]; // vertex of the triangle
|
|
triangle *neigh[3]; // neighbors of the triangle
|
|
double cx, cy; // center of the triangle's circumcircle
|
|
double cr; // radius of the circumcircle
|
|
std::vector<dem_point*> hosted_dem; // DEM points that are located within the triangle
|
|
}
|
|
```
|
|
|
|
##### dem_point
|
|
|
|
DEM point defined on the 2-D Cartesian coordinate. It is used to store the input DEM data. Included variables are as following:
|
|
|
|
```c++
|
|
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; // pointer of the triangle that the dem_point falls inside of
|
|
}
|
|
```
|
|
|
|
#### Tools
|
|
|
|
##### grd2tin: generation of the TIN using regular DEM data
|
|
|
|
###### usage
|
|
|
|
```shell
|
|
grd2tin -f<grid-file> -r<xmin>/<xmax>/<ymin>/<ymax> -i<dx>/<dy> -m<mesh-file> [-p<poly-file>] [-t<threshold>] [-l<log-file>] [-n<neighbor-file>] [-z]
|
|
```
|
|
|
|
###### options
|
|
|
|
* **-f** Input DEM data. The program takes DEM data that are stored as a simple ASCII text file. Each line of the file contains the _x_, _y_ and _elevation_ values of a DEM point separated by spaces. Moreover, the DEM data should be stored in an order that starts from the lower-left corner of the DEM grid and travels in a row-major manner till the upper-right corner of the grid. Specially, the _x_ and _y_ values in the file could be omitted by setting the **-z** option.
|
|
* **-r** Range of the input DEM grid in the x and y directions, respectively.
|
|
* **-i** Intervals of the input DEM grid in the x and y directions, respectively.
|
|
* **-m** Output Gmsh file (.msh) of the generated TIN.
|
|
* **-p (optional)** Input text file of a polygon to control the outline shape of the generated TIN. The polygon is represented using its corners' locations. Each line of the file should contain the _x_, _y_ values of a corner vertex. The vertexes could be ordered either clockwise or anti-clockwise.
|
|
* **-t (optional)** Threshold of the maximal error of the generated TIN with respect to the input DEM grid.
|
|
* **-l (optional)** Output text file of a log file of the maximal error of the generated TIN.
|
|
* **-n (optional)** Output text file of neighbor-ships of the generated TIN.
|
|
* **-z (optional)** The input DEM grid is a 1-column z-table.
|
|
|
|
##### rnd2tin: generation of the TIN using random DEM data
|
|
|
|
###### usage
|
|
|
|
```shell
|
|
rnd2tin -f<xyz-file> -m<mesh-file> [-p<poly-file>] [-t<threshold>] [-l<log-file>] [-n<neighbor-file>]
|
|
```
|
|
|
|
###### options
|
|
|
|
* **-f** Input DEM data. The program takes DEM data that are stored as a simple ASCII text file. Each line of the file contains the _x_, _y_ and _elevation_ values of a DEM point separated by spaces.
|
|
* **-m** Output Gmsh file (.msh) of the generated TIN.
|
|
* **-p (optional)** Input text file of a polygon to control the outline shape of the generated TIN. The polygon is represented using its corners' locations. Each line of the file should contain the _x_, _y_ values of a corner vertex. The vertexes could be ordered either clockwise or anti-clockwise.
|
|
* **-t (optional)** Threshold of the maximal error of the generated TIN with respect to the input DEM grid.
|
|
* **-l (optional)** Output text file of a log file of the maximal error of the generated TIN.
|
|
* **-n (optional)** Output text file of neighbor-ships of the generated TIN.
|
|
|
|
#### Examples
|
|
|
|
The following is a simple example for using the library to generate the TIN you see on top of this page. More examples could be found at the _src/demo_ folder.
|
|
|
|
```c++
|
|
#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();
|
|
|
|
// prepare variables and vectors
|
|
std::vector<double> err_records;
|
|
std::vector<vertex2dc*> tin_vert;
|
|
std::vector<triangle*> tin_ele;
|
|
|
|
// call the grd2tin function to generate the TIN
|
|
// the resultant vertexes and facets are stored in
|
|
// vectors tin_vert and tin_ele, respetively.
|
|
grd2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records);
|
|
|
|
// Write a log file of the construciton process
|
|
// which you can examine later.
|
|
std::ofstream logfile("data/topo_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 for visualization
|
|
std::ofstream outfile("data/topo_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 neighboring file
|
|
outfile.open("data/topo_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 grd2tin 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;
|
|
}
|
|
```
|
|
|