Crate triangulate

source ·
Expand description

triangulate

Subdivides a set of non-self-intersecting polygons into a set of non-overlapping triangles. Inputs and outputs can be customized to use your required formats to avoid unnecessary conversions.

 
// A hollow square shape
//  ________
// |  ____  |
// | |    | |
// | |____| |
// |________|
let polygons = vec![
    vec![[0f32, 0f32], [0., 1.], [1., 1.], [1., 0.]], 
    vec![[0.05, 0.05], [0.05, 0.95], [0.95, 0.95], [0.95, 0.05]]
];
let mut triangulated_indices = Vec::<[usize; 2]>::new();
polygons.triangulate(formats::IndexedListFormat::new(&mut triangulated_indices).into_fan_builder()).expect("Triangulation failed");
println!("First triangle: {:?}, {:?}, {:?}", 
    polygons.get_vertex(triangulated_indices[0]), 
    polygons.get_vertex(triangulated_indices[1]), 
    polygons.get_vertex(triangulated_indices[2]));

Any type that implements Polygon or PolygonList can be triangulated. Most commonly that would be Vec<_> or Vec<Vec<_>> (where _: Vertex, such as [f32; 2]), but you can implement the trait on your own types.

The output format is also customizable. PolygonList::triangulate takes a FanFormat, which determines the resulting output. Most commonly, you would want formats::IndexedListFormat, which stores three indices for every generated triangle in a List (like Vec). However, this is a ListFormat (it takes individual triangles instead of triangle fans), so it must be converted to a FanFormat by calling ListFormat::into_fan_format (see the example above). Another useful format is formats::DeindexedListFormat, which deindexes each triangle point to create a List of the actual vertices.

Input traits

Output traits

Preconditions

  • No edge can cross any other edge, whether it is on the same polygon or not.
  • Each vertex must be part of exactly two edges. Polygons cannot ‘share’ vertices with each other.
  • Each vertex must be distinct - no vertex can have x and y coordinates that both compare equal to another vertex’s.

These preconditions are not explicitly checked, but an invalid polygon set will likely yield TriangulationError::InternalError.

Results

Because the algorithm involves random ordering, the exact triangulation is not guaranteed to be same between invocations.

Algorithm

This library is based on Raimund Seidel’s randomized algorithm for triangulating polygons. The expected runtime for each polygon or hole with n vertices is O(n log* n), a near-linear runtime.

Modules

Structs

Enums

Traits

  • A triangle fan with vertices of type V
  • Performs the construction of triangle fans
  • Describes the construction and layout of a triangle fans
  • A collection of multiple Fans.
  • A list of triangles represented as triplets of vertices of type V
  • Performs the construction of a triangle list
  • Describes the construction and layout of a triangle list
  • A type which can map its members of type T to other types (e.g. [usize; 2] is Mappable over usize to produce [u16; 2], [u32; 2], etc.)
  • An indexable polygon’s vertices
  • An indexable list of polygons and their vertices
  • A trait for real number types that do not necessarily have floating-point-specific characteristics such as NaN and infinity.
  • A two-dimensional point.
  • A type which can be used to index a specific Vertex. Automatically implemented for all Eq + Clone types