220 lines
7.2 KiB
C++
220 lines
7.2 KiB
C++
/**
|
|
* ___________ __
|
|
* /_ __/ _/ | / /
|
|
* / / / // |/ /
|
|
* / / _/ // /| /
|
|
* /_/ /___/_/ |_/
|
|
*
|
|
* C++ library of the Triangular Irregular Network (TIN)
|
|
*
|
|
* Copyright (c) 2021-2031 Yi Zhang (zhangyiss@icloud.com)
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#ifndef _TIN_DELAUNAY_H
|
|
#define _TIN_DELAUNAY_H
|
|
#include "cmath"
|
|
#include "vector"
|
|
#include "algorithm"
|
|
|
|
#define ZERO 1e-5
|
|
|
|
// Start vertex definition
|
|
struct vertex2dc
|
|
{
|
|
unsigned int id; // index of the vertex
|
|
double x, y; // position of the vertex
|
|
double elev; // elevation at the vertex
|
|
|
|
vertex2dc();
|
|
|
|
/**
|
|
* @brief Construct a new vertex2dc object
|
|
*
|
|
* @param inx initial x coordinate
|
|
* @param iny initial y coordinate
|
|
* @param inelev initial elevation
|
|
* @param inid initial index
|
|
*/
|
|
vertex2dc(double inx, double iny, double inelev, unsigned int inid);
|
|
|
|
/**
|
|
* @brief Set a vertex2dc object
|
|
*
|
|
* @param inx initial x coordinate
|
|
* @param iny initial y coordinate
|
|
* @param inelev initial elevation
|
|
* @param inid initial index
|
|
*/
|
|
void set(double inx, double iny, double inelev, unsigned int inid);
|
|
};
|
|
|
|
/**
|
|
* @brief Compare two vertexes
|
|
*
|
|
* @param a vertex a
|
|
* @param b vertex b
|
|
* @return true the two vertexes are at the same location
|
|
* @return false the two vertexes are not at the same location
|
|
*/
|
|
bool operator ==(const vertex2dc &a, const vertex2dc &b);
|
|
|
|
/**
|
|
* @brief Test if the three points are on the same line
|
|
*
|
|
* @param a_ptr pointer of the vertex a
|
|
* @param b_ptr pointer of the vertex b
|
|
* @param c_ptr pointer of the vertex c
|
|
* @return true the three vertexes are on the same line
|
|
* @return false the three vertexes are not on the same line
|
|
*/
|
|
bool is_collinear(vertex2dc *a_ptr, vertex2dc *b_ptr, vertex2dc *c_ptr);
|
|
|
|
/**
|
|
* @brief Calculate the circumcircle from three points
|
|
*
|
|
* @param v0 pointer of the vertex v0
|
|
* @param v1 pointer of the vertex v1
|
|
* @param v2 pointer of the vertex v2
|
|
* @param cx x coordinate of the returned circumcircle
|
|
* @param cy y coordinate of the returned circumcircle
|
|
* @param cr squared radius of the returned circumcircle
|
|
*/
|
|
void circumcircle(vertex2dc *v0, vertex2dc *v1, vertex2dc *v2, double &cx, double &cy, double &cr);
|
|
// End vertex definition
|
|
|
|
// Start DEM definition
|
|
struct triangle;
|
|
|
|
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;
|
|
|
|
dem_point();
|
|
|
|
/**
|
|
* @brief Construct a new DEM point object
|
|
*
|
|
* @param inx initial x coordinate
|
|
* @param iny initial y coordinate
|
|
* @param inelev initial elevation
|
|
*/
|
|
dem_point(double inx, double iny, double inelev);
|
|
|
|
/**
|
|
* @brief Set a DEM point object
|
|
*
|
|
* @param inx initial x coordinate
|
|
* @param iny initial y coordinate
|
|
* @param inelev initial elevation
|
|
*/
|
|
void set(double inx, double iny, double inelev);
|
|
};
|
|
// End DEM definition
|
|
|
|
/* Start triangle definition
|
|
* v2
|
|
* /\
|
|
* / \
|
|
* n2 / \ n1
|
|
* / \
|
|
* /------------\
|
|
* v0 n0 v1
|
|
*/
|
|
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;
|
|
|
|
triangle();
|
|
|
|
/**
|
|
* @brief Construct a new triangle object
|
|
*
|
|
* @param v0ptr pointer of the vertex 0
|
|
* @param v1ptr pointer of the vertex 1
|
|
* @param v2ptr pointer of the vertex 2
|
|
*/
|
|
triangle(vertex2dc *v0ptr, vertex2dc *v1ptr, vertex2dc *v2ptr);
|
|
|
|
/**
|
|
* @brief Set a triangle object
|
|
*
|
|
* @param v0ptr pointer of the vertex 0
|
|
* @param v1ptr pointer of the vertex 1
|
|
* @param v2ptr pointer of the vertex 2
|
|
*/
|
|
void set(vertex2dc *v0ptr, vertex2dc *v1ptr, vertex2dc *v2ptr);
|
|
|
|
/**
|
|
* @brief Set neighbors of a triangle object
|
|
*
|
|
* @param n0ptr pointer of the neighboring vertex 0
|
|
* @param n1ptr pointer of the neighboring vertex 1
|
|
* @param n2ptr pointer of the neighboring vertex 2
|
|
*/
|
|
void set_neighbor(triangle *n0ptr, triangle *n1ptr, triangle *n2ptr);
|
|
|
|
/**
|
|
* @brief Test if the location is inside the triangle
|
|
*
|
|
* @param inx x coordinate of the input location
|
|
* @param iny y coordinate of the input location
|
|
* @return true the input location is inside the triangle
|
|
* @return false the input location is not inside the triangle
|
|
*/
|
|
bool bound_location(double inx, double iny);
|
|
|
|
/**
|
|
* @brief Interpolate the elevation of the given location inside the triangle
|
|
*
|
|
* @param inx x coordinate of the input location
|
|
* @param iny y coordinate of the input location
|
|
* @return double the interpolated elevation at the input location
|
|
*/
|
|
double interpolate(double inx, double iny);
|
|
};
|
|
// End triangle definition
|
|
|
|
/**
|
|
* @brief Generate the TIN from the 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
|
|
* @param[in] xmax The maximal coordinate of the DEM grid on the x-axis
|
|
* @param[in] ymin The minimal coordinate of the DEM grid on the y-axis
|
|
* @param[in] ymax The maximal coordinate of the DEM grid on the y-axis
|
|
* @param[in] dx Data spacing of the DEM grid on the x-axis
|
|
* @param[in] dy Data spacing of the DEM grid on the y-axis
|
|
* @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] 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);
|
|
|
|
/**
|
|
* @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 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] 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<double> *err_records = nullptr);
|
|
|
|
#endif // _TIN_DELAUNAY_H
|