iShape-Rust / iOverlay

Boolean Operations for 2D Polygons: Supports intersection, union, difference, xor, and self-intersections for all polygon varieties.
https://ishape-rust.github.io/iShape-js/
MIT License
32 stars 3 forks source link
boolean-operations cad clipper clipping computational-geometry difference eda geometry gis intersection poly-bool polygon polygon-clipping self-intersection union xor

iOverlay

crates.io version docs.rs docs

Balloons

The iOverlay library provides high-performance boolean operations on polygons, including union, intersection, difference, and xor. It is designed for applications that require precise polygon operations, such as computer graphics, CAD systems, and geographical information systems (GIS). By supporting both integer (i32) and floating-point (f32, f64) APIs, iOverlay offers flexibility and precision across diverse use cases.

For detailed performance benchmarks, check out the Performance Comparison

Documentation

Try out iOverlay with an interactive demo:

Features

Getting Started

Add the following to your Cargo.toml:

[dependencies]
i_overlay = "^1.7"

Hello world

Let's union two squares

f64 Example

let subj = [
    // Define the subject polygon (a square)
    F64Point::new(-10.0, -10.0),
    F64Point::new(-10.0, 10.0),
    F64Point::new(10.0, 10.0),
    F64Point::new(10.0, -10.0),
].to_vec();

let clip = [
    // Define the clip polygon (a slightly shifted square)
    F64Point::new(-5.0, -5.0),
    F64Point::new(-5.0, 15.0),
    F64Point::new(15.0, 15.0),
    F64Point::new(15.0, -5.0),
].to_vec();

let mut overlay = F64Overlay::new();

overlay.add_path(subj, ShapeType::Subject);
overlay.add_path(clip, ShapeType::Clip);

let graph = overlay.into_graph(FillRule::NonZero);
let shapes = graph.extract_shapes(OverlayRule::Union);

println!("shapes count: {}", shapes.len());

if shapes.len() > 0 {
    let contour = &shapes[0][0];
    println!("shape 0 contour: ");
    for p in contour {
        let x = p.x;
        let y = p.y;
        println!("({}, {})", x, y);
    }
}

The result of the extract_shapes function for f64 returns a Vec<F64Shapes>:

Note: Outer boundary paths have a clockwise order, and holes have a counterclockwise order. More information about contours.

i32 Example

let subj = [
    // Define the subject polygon (a square)
    IntPoint::new(-10, -10),
    IntPoint::new(-10, 10),
    IntPoint::new(10, 10),
    IntPoint::new(10, -10),
].to_vec();

let clip = [
    // Define the clip polygon (a slightly shifted square)
    IntPoint::new(-5, -5),
    IntPoint::new(-5, 15),
    IntPoint::new(15, 15),
    IntPoint::new(15, -5),
].to_vec();

let shapes = Overlay::with_paths(&[subj], &[clip])
    .into_graph(FillRule::NonZero)
    .extract_shapes(OverlayRule::Union);

println!("shapes count: {}", shapes.len());

if shapes.len() > 0 {
    let contour = &shapes[0][0];
    println!("shape 0 contour: ");
    for p in contour {
        let x = p.x;
        let y = p.y;
        println!("({}, {})", x, y);
    }
}

The extract_shapes function for i32 returns a Vec<IntShapes>:

Note: Outer boundary paths have a clockwise order, and holes have a counterclockwise order. More information about contours.

Overlay Rules

AB

Union, A or B

Union

Intersection, A and B

Intersection

Difference, A - B

Difference

Inverse Difference, B - A

Inverse Difference

Exclusion, A xor B

Exclusion