Simple rust library for finding centerlines of 2D closed geometry
  • Rust 99%
  • Shell 1%
Find a file
eadf b968a2ff37
All checks were successful
ci/woodpecker/push/test/2 Pipeline was successful
ci/woodpecker/push/test/1 Pipeline was successful
ci/woodpecker/tag/test/1 Pipeline was successful
ci/woodpecker/tag/test/2 Pipeline was successful
0.14.0
2025-12-04 15:17:03 +01:00
.cargo Using new vector-traits 2025-05-18 19:53:04 +02:00
.github/workflows Added " --all-features" to workflows 2023-11-15 17:36:42 +01:00
.woodpecker bumped fltk to ^1.5.8 2025-05-12 15:01:06 +02:00
benches Added from_cols_array() and finalized the safe_inverse() methods 2025-04-10 22:20:09 +02:00
example Adapted to changes in boostvoronoi 2025-12-03 00:39:06 +01:00
img Added a logo 2021-07-04 22:41:57 +02:00
src 0.14.0 2025-12-04 15:17:03 +01:00
tests 0.8.0 2023-10-28 15:35:21 +02:00
.gitignore bumped fltk to ^1.5.8 2025-05-12 15:01:06 +02:00
Cargo.toml 0.14.0 2025-12-04 15:17:03 +01:00
LICENSE-APACHE 0.8.0 2023-10-28 15:35:21 +02:00
LICENSE-MIT 0.8.0 2023-10-28 15:35:21 +02:00
README.md bumped deps 2025-12-01 23:55:01 +01:00
run_grcov.sh Adapted to linestring 0.11.0 and vector-traits 0.3.0 2023-11-10 16:39:04 +01:00

crates.io Documentation status-badge dependency status license

This simple library tries to find center-lines, aka the median-axis, of closed 2D geometries.

It is focused on letter like shapes, i.e. vertex loops with potential enclosed islands of loops. Loops directly connected to other loops does not work at the moment.

It uses a segmented voronoi diagram as a base, then it filters out the 'spiky' bits (green) by comparing the angle between the edge (green), and the input geometry (red) that created it. If the angle is close to 90°, it will be ignored. Note that the result (blue) technically is not a true centerline after the spikes has been filtered out, but it makes for much cleaner tool-paths etc. It also performs a line simplification on the resulting center-line.

unfiltered filtered

let segments = ...same as boost voronoi segments...
let mut centerline = Centerline::<i32, glam::Vec3>::::with_segments(segments);
centerline.build_voronoi()?;
// the cosine value of the angle limit. 
let cos_angle:f32 = 0.38;
// the RDP simplification distance
let centerline_simplification:f32 = 0.1;

centerline.calculate_centerline(cos_angle, centerline_simplification, None)?;
println!(
   "Result: lines:{}, line_strings:{}",
   centerline.lines.as_ref().map_or(0,|x|x.len()),
   centerline.line_strings.as_ref().map_or(0,|x|x.len())
);

Gui example

cargo run --example fltk_gui --features=obj-rs --release

The example only displays 2D, but the generated center-line is actually 3D line segments.
The Z coordinate is the distance between the 2D center-line, and the geometry that created it.

The example GUI takes .obj files as input. The .obj file needs to be 2D in some axis aligned plane (one of the coordinates needs to be zero). Also make sure there are no intersecting outer edges.

Todo

  • Add better tests
  • Sometimes a shape registers as 'outside' it's convex hull
  • Add opengl to fltk_gui so that the 3D aspect of the center-line can be visualized.

Contributing

We welcome contributions from the community. Feel free to submit pull requests or report issues on our GitHub repository. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Minimum Supported Rust Version (MSRV)

The minimum supported version of Rust for centerline is 1.87.0.

License

Licensed under either of

at your option.