
[](https://crates.io/crates/boostvoronoi)
[](https://docs.rs/boostvoronoi)
[](https://ci.codeberg.org/repos/12854)
[](https://deps.rs/crate/boostvoronoi/0.12.0)

# Segmented Voronoi for Rust
[Boost 1.76.0 polygon::voronoi](https://www.boost.org/doc/libs/1_76_0/libs/polygon/doc/voronoi_main.htm) ported to 100% rust.
This implementation of [Fortune's algorithm](https://en.wikipedia.org/wiki/Fortune%27s_algorithm) works for line segments as well as points, making it useful for calculating centerlines [(like the title image above)](https://github.com/eadf/toxicblend.rs).
Code still in development, there are still bugs. However, all the remaining bugs I've noticed are also present in C++ boost voronoi.
Gui example:
```sh
cargo run --example fltk_gui
```
* Mouse click to place new points.
* Press and hold 'L' + mouse click to add a single line.
* Press and hold 'S' + mouse click to add strings of lines.
* Use mouse wheel to zoom.
* Mouse click and drag to pan.
API example:
```rust
use boostvoronoi::prelude::*;
type I = i32; // this is the integer input type
fn main() -> Result<(), BvError> {
// Only unique Points will be used. Points should not
// intersect lines.
let points: [[I; 2]; 1] = [[9, 10]];
// Lines may only intersect at the endpoints.
let segments: [[I; 4]; 1] = [[10, 11, 12, 33]];
let diagram = Builder::<I>::default()
// You will have to keep track of the input geometry. it
// will be referenced as input geometry indices in the
// output.
// `with_vertices()` accepts iterators of anything that
// implements `Into<boostvoronoi::Point>`
.with_vertices(points.iter())?
// `with_segments()` accepts iterators of anything that
// implements `Into<boostvoronoi::Line>`
.with_segments(segments.iter())?
// this will generate the list of cells, edges and circle
// events (aka vertices)
.build()?;
println!(
"Result: cells:{}, edges:{}, vertices:{}",
diagram.cells().len(),
diagram.edges().len(),
diagram.vertices().len()
);
for cell in diagram.cells().iter() {
println!("Cell : {:?}", cell.id());
for edge_id in diagram.cell_edge_iterator(cell.id()) {
let edge = diagram.edge(edge_id)?;
// The vertices of an edge will have the value `None`
// if they are infinitely far away.
println!(
" edge: {edge_id:?}, from:{:?} to:{:?}",
edge.vertex0(),
diagram.edge_get_vertex1(edge_id)?
);
}
}
Ok(())
}
```
Edges will become curves when line segments are used as input, see the example code for discretization and interpolation.
### Minimum Supported Rust Version (MSRV)
The minimum supported version of Rust for `boostvoronoi` is `1.87.0`.
## Todo
- [ ] Try to fix the known problems in C++ Boost voronoi and port over.
- [ ] Add many more test cases for `voronoi_robust_ftp.rs`.
- [ ] Benchmark and optimize.
- [ ] Replace C++ style boolean ordering functors.
- [ ] Replace builtin ulp with some rust crate (approx?).
- [ ] Take care of the `todo:` tags.
- [x] Builder pattern
- [x] Hide implementation details with a workspace (w/o disabling doc-tests)
- [x] Add `serde` to `SyncDiagram` and other diagram types.
- [x] Specific type conversion tests (`cgmath`,`glam`,`mint` & `geo`)
All credit goes to the original author ([Andrii Sydorchuk](https://github.com/asydorchuk)) and the [boost contributors](https://github.com/boostorg/polygon), except the porting mistakes. They are all mine.