i_overlay 1.7.4

Boolean Operations for 2D Polygons: Supports intersection, union, difference, xor, and self-intersections for all polygon varieties.
Documentation

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

  • Operations: union, intersection, difference, and exclusion.
  • Polygons: with holes, self-intersections, and multiple paths.
  • Simplification: removes degenerate vertices and merges collinear edges.
  • Fill Rules: even-odd and non-zero.
  • Data Types: Supports i32, f32, and f64 APIs.

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>:

  • Vec<F64Shape>: A collection of shapes.
  • F64Shape: Represents one shape, consisting of:
    • Vec<F64Path>: A list of paths (contours).
    • The first path is the outer boundary (clockwise), and subsequent paths represent holes (counterclockwise).
  • F64Path: A series of points (Vec<F64Point>) forming a closed contour.

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>:

  • Vec<IntShape>: A collection of shapes.
  • IntShape: Represents a shape made up of:
    • Vec<IntPath>: A list of paths (contours).
    • The first path is the outer boundary (clockwise), and subsequent paths represent holes (counterclockwise).
  • IntPath: A sequence of points (Vec<IntPoint>) forming a closed contour.

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

Overlay Rules

Union, A or B

Intersection, A and B

Difference, A - B

Inverse Difference, B - A

Exclusion, A xor B