iTriangle
iTriangle is a high-performance 2D polygon triangulation library for Rust. It solves robust triangulation for real-world, messy input (holes, self-intersections, mixed winding) and is built for GIS/CAD, simulation, and rendering pipelines that need deterministic results.
For detailed performance benchmarks, check out the Performance Comparison
Table of Contents
- Why iTriangle?
- Features
- Architecture Overview
- Quick Start
- Documentation
- Examples
- Integer API
- Performance
- Gallery
- Contributing
- License
Why iTriangle?
- Robust on complex input: supports holes and self-intersections with automatic resolution.
- Deterministic and stable: integer-based core avoids floating-point corner cases.
- High-performance: optimized sweep-line triangulation with cache-friendly outputs.
- Flexible outputs: Delaunay, convex decomposition, tessellation, and centroid nets.
Features
- Sweep-line Triangulation - Fast and simple triangulation of polygons with or without holes.
- Delaunay Triangulation - Efficient and robust implementation for generating Delaunay triangulations.
- Self-Intersection Handling – Fully supports self-intersecting polygons with automatic resolution.
- Adaptive Tessellation - Refine Delaunay triangles using circumcenters for better shape quality.
- Convex Decomposition - Convert triangulation into convex polygons.
- Centroidal Polygon Net: Build per-vertex dual polygons using triangle centers and edge midpoints.
- Steiner Points: Add custom inner points to influence triangulation.
- GPU-Friendly Layout: Triangles and vertices are naturally ordered by X due to the sweep-line algorithm, improving cache locality for rendering.
Architecture Overview
Quick Start
Add to your Cargo.toml:
[]
= "0.43"
Minimal example:
use Triangulatable;
let contour = vec!;
let triangulation = vec!.triangulate.;
println!;
By default, float input is converted to the robust integer core using i32
coordinates. If your geometry needs a different integer precision, choose it
explicitly:
use Triangulatable;
use Triangulator;
let shape = vec!;
// One-shot triangulation with i64 integer coordinates.
let mesh = shape..;
// Reusable triangulator: first generic is index type, second is coordinate type.
let mut triangulator = default;
let mesh = triangulator.triangulate;
Documentation
Examples
Single Shape Triangulation
use Triangulatable;
use Triangulation;
let shape = vec!;
let triangulation = shape.triangulate.;
println!;
println!;
let delaunay_triangulation: =
shape.triangulate.into_delaunay.to_triangulation;
println!;
println!;
let convex_polygons = shape.triangulate.into_delaunay.to_convex_polygons;
println!;
let tessellation: = shape
.triangulate
.into_delaunay
.refine_with_circumcenters_by_obtuse_angle
.to_triangulation;
println!;
println!;
let centroids = shape
.triangulate
.into_delaunay
.refine_with_circumcenters_by_obtuse_angle
.to_centroid_net;
println!;
💡 Output: Triangle indices and vertices, where all triangles oriented in a counter-clockwise direction.
Triangulating Multiple Shapes Efficiently
If you need to triangulate many shapes, it is more efficient to use Triangulator.
use Triangulation;
use Triangulator;
let contours = vec!;
// Uses u32 triangle indices and the default i32 integer coordinate solver.
let mut triangulator = default;
// Enable Delaunay refinement
triangulator.delaunay;
// Use fast Earcut solver for contours with ≤ 64 points
triangulator.earcut;
let mut triangulation = with_capacity;
for contour in contours.iter
Integer API
The integer API is useful when your coordinates are already quantized or when you want direct control over the robust integer core. It avoids float-to-int adapter setup and returns integer points unchanged.
Use IntPoint with IntContour, IntShape, or IntShapes-compatible containers:
use IntTriangulatable;
use IntPoint;
let contour = vec!;
let triangulation = contour.triangulate.;
assert_eq!;
assert_eq!;
For repeated triangulation, use IntTriangulator and reuse its internal buffers:
use IntTriangulation;
use IntTriangulator;
use IntPoint;
let contours = vec!;
let mut triangulator = default;
let mut output = default;
for contour in &contours
If your integer contours are already valid and correctly oriented, the unchecked API skips validation:
use IntUncheckedTriangulatable;
use IntPoint;
let contour = vec!;
let triangulation = contour.uncheck_triangulate.;
assert_eq!;
Performance
Benchmarks and interactive demos are available here:
Gallery
| Delaunay | Convex Polygons | Steiner Points |
|---|---|---|
| Tessellation | Centroid Net | |
|---|---|---|
Contributing
See CONTRIBUTING.md for development setup, tests, and PR guidelines.
License
Licensed under either of:
- MIT license (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)