delatin/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
/*!
Simple and fast [**TIN**](https://en.wikipedia.org/wiki/Triangulated_irregular_network) generation library.
Uses [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation).
# Example
```rust
use delatin::{triangulate, Error};
let heights = vec![100.1, 123.4, 111.5, 121.4];
let width = 2;
let height = 2;
let max_error = Error(1.0);
// points `Vec<(usize, usize)>`: A vector containing all the vertices of the triangulated mesh. Each point corresponds to heights vector index.
// triangles `Vec<(usize, usize, usize)>`: A vector containing all the triangles of the mesh, each defined by indices into the `points`.
let (points, triangles) = triangulate(&heights, width, height, max_error)?;
```
*/
use std::fmt;
pub use error::TriangulationError;
use triangulation::Triangulation;
mod error;
mod priority_queue;
mod triangulation;
mod utils;
// TODO: consider NewTypes
type Point = (usize, usize);
type Triangle = (usize, usize, usize);
type Height = f64;
/// Error for the triangulation process.
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
pub struct Error(pub f64);
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
/// Runs the triangulation process until the maximum error is below the specified threshold.
///
/// # Arguments
///
/// * `height_data` - Height values of the grid.
/// * `dimesions` - Tuple width and height of the grid.
/// * `max_error` - The maximum allowable error for the triangulation process.
///
/// # Returns
///
/// Tuple containing:
/// - points `Vec<(usize, usize)>`: A vector containing all the vertices of the triangulated mesh.
/// - triangles `Vec<(usize, usize, usize)>`: A vector containing all the triangles of the mesh, each defined by indices into the `points`.
///
/// # Errors
///
/// - `InvalidDataLengthError` - If the length of the height data does not match the width and height of the grid.
/// - `MaxErrorRetrievalError` - If the maximum error is not found in the priority queue.
/// - `EmptyQueueError` - If the priority queue is empty during triangulation.
///
pub fn triangulate(
height_data: &[f64],
dimesions: (usize, usize),
max_error: Error,
) -> Result<(Vec<Point>, Vec<Triangle>), TriangulationError> {
let width = dimesions.0;
let height = dimesions.1;
(height_data.len() == width * height)
.then_some(())
.ok_or(TriangulationError::InvalidDataLengthError)?;
let mut delatin = Triangulation::new(height_data, width, height);
delatin.run(max_error)
}