| Crates.io | poly_surge |
| lib.rs | poly_surge |
| version | 0.1.0 |
| created_at | 2025-12-21 03:43:08.873166+00 |
| updated_at | 2025-12-21 03:43:08.873166+00 |
| description | Somewhat novel, fast incremental polytope surgery in Rust. Add and remove halfspaces, 11x-1200x faster than the standard 'just reconstruct it' approach. |
| homepage | |
| repository | https://github.com/YOUR_USERNAME/poly_surge |
| max_upload_size | |
| id | 1997310 |
| size | 625,018 |
Somewhat novel, fast incremental polytope surgery in Rust. Add and remove halfspaces, 23×–862x faster than the standard "just reconstruct it" approach.
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.
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
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:
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.
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
Licensed under either of:
at your option.