poly_surge

Crates.iopoly_surge
lib.rspoly_surge
version0.1.0
created_at2025-12-21 03:43:08.873166+00
updated_at2025-12-21 03:43:08.873166+00
descriptionSomewhat novel, fast incremental polytope surgery in Rust. Add and remove halfspaces, 11x-1200x faster than the standard 'just reconstruct it' approach.
homepage
repositoryhttps://github.com/YOUR_USERNAME/poly_surge
max_upload_size
id1997310
size625,018
(consistent-milk12)

documentation

https://docs.rs/poly_surge

README

poly_surge

Somewhat novel, fast incremental polytope surgery in Rust. Add and remove halfspaces, 23×–862x faster than the standard "just reconstruct it" approach.

What is this?

A convex polytope in 3D is a bounded region defined by the intersection of half-spaces. This crate lets you dynamically add and remove these half-space constraints while preserving the mesh topology (vertices, edges, faces)—no full reconstruction required.

Quick Start

use poly_surge::{IncrementalPolytope, HalfSpace};
use glam::DVec3;

// Create a polytope and add planes to form a cube
let mut polytope = IncrementalPolytope::new();

// Six faces of a unit cube centered at origin
let planes = [
    HalfSpace::new(DVec3::X, 0.5),    // +X face
    HalfSpace::new(-DVec3::X, 0.5),   // -X face
    HalfSpace::new(DVec3::Y, 0.5),    // +Y face
    HalfSpace::new(-DVec3::Y, 0.5),   // -Y face
    HalfSpace::new(DVec3::Z, 0.5),    // +Z face
    HalfSpace::new(-DVec3::Z, 0.5),   // -Z face
];

for plane in planes {
    polytope.add_plane(plane);
}

assert_eq!(polytope.vertex_count(), 8);  // Cube has 8 vertices
assert!(polytope.is_bounded());

// Remove one face - the cube becomes an infinite prism
let plane_to_remove = polytope.planes().next().unwrap().0;
polytope.remove_plane(plane_to_remove);

assert!(!polytope.is_bounded());  // Now unbounded

Features

  • Incremental construction: Add planes one at a time with O(V + E) clipping
  • Topology-based removal: Remove planes in ~O(N) typical time (vs O(N log N + V) rebuild)
  • Lazy evaluation: Edges and face orderings built on-demand
  • Unbounded support: Handles infinite polytopes via homogeneous coordinates
  • Lazy boundedness check: O(1) query when cached, O(N log N) rebuild when dirty

When to Use

  • Dynamic Voronoi diagrams (cell modification)
  • CSG operations on halfspace-defined solids
  • Robot motion planning (C-space constraint relaxation)
  • Interactive geometry editors
  • Physics simulation (constraint relaxation)

When NOT to Use

  • N > 10,000 planes (consider specialized data structures)
  • Exact arithmetic required (we use f64 with epsilon tolerance)
  • Batch deletion of many planes at once (single rebuild may be faster)

Performance

Benchmarks on Fibonacci-sphere polytopes (release mode, cargo bench):

Planes Topology-Based Rebuild (incremental add_plane) vs Rebuild
30 17 μs 376 μs 23×
50 28 μs 1,433 μs 51×
80 43 μs 5,079 μs 119×
100 52 μs 9,638 μs 186×
150 76 μs 33,020 μs 436×
200 96 μs 82,500 μs 862×

Scalability: Near-linear O(N) — approximately 0.8 μs per plane.

Real-world proxies:

  • Voronoi cell update (14 planes): ~20 μs
  • CSG cube intersection (12 planes): ~11 μs

Algorithm

The removal algorithm exploits vertex topology: when a plane is removed, vertices with only 2 remaining incident planes lie on a line. We search along that line to find where it hits other constraints, reconstructing the "unclipped" geometry.

See ResearchProposal.md for the full algorithm documentation.

Origin & Attribution

This algorithm was developed as a hobby project while working on transforming the vertex enumeration code in the demiurge library. The ideas discussed and extended were directly influenced by the vertex enumeration literature and the practical challenges encountered in that codebase.

Original implementation: https://gitlab.com/dryad1/demiurge

License

Licensed under either of:

at your option.

Commit count: 0

cargo fmt