pub struct Polygon { /* private fields */ }Expand description
A simple polygon, optionally with holes, on the i16 lattice.
§Invariants
A Polygon can only be constructed through Polygon::new or
Polygon::from_outer, which enforce that:
- Ring 0 is the outer boundary; rings
1..are holes. - The outer ring winds counter-clockwise and holes wind clockwise, so the polygon’s interior is always on the left of every directed edge. Rings supplied the other way round are reversed automatically.
- Every coordinate is within
Point::MIN_COORD..=Point::MAX_COORD. - Every ring has at least 3 vertices, no repeated consecutive vertices, and encloses a non-zero area.
- No two edges cross, and no vertex is a zero-width spike.
- Every hole lies inside the outer ring.
The uniform “interior on the left” rule is what lets the wavefront treat
outer boundary and holes identically — see docs/ALGORITHM.md.
§Vertex and edge numbering
Vertices are numbered 0..n across all rings, outer ring first. Edge i
starts at vertex i; see EdgeId.
§Examples
use straight_skeleton::{Point, Polygon};
// A square. Winding is fixed up for you.
let square = Polygon::from_outer(&[
Point::new(0, 0),
Point::new(10, 0),
Point::new(10, 10),
Point::new(0, 10),
])?;
assert_eq!(square.vertex_count(), 4);
assert_eq!(square.ring_count(), 1);
// A square with a square hole.
let with_hole = Polygon::new(
&[Point::new(0, 0), Point::new(30, 0), Point::new(30, 30), Point::new(0, 30)],
&[vec![
Point::new(10, 10),
Point::new(20, 10),
Point::new(20, 20),
Point::new(10, 20),
]],
)?;
assert_eq!(with_hole.ring_count(), 2);
assert_eq!(with_hole.vertex_count(), 8);Implementations§
Source§impl Polygon
impl Polygon
Sourcepub const MAX_VERTICES: usize
pub const MAX_VERTICES: usize
The largest number of vertices a polygon may have.
Bounded by VertexId’s u16, minus one so that “one past the end”
indices cannot overflow.
Sourcepub fn new(outer: &[Point], holes: &[Vec<Point>]) -> Result<Self, PolygonError>
pub fn new(outer: &[Point], holes: &[Vec<Point>]) -> Result<Self, PolygonError>
Builds a polygon from an outer ring and a list of holes.
Ring winding is normalised for you: the outer ring is made counter-clockwise and holes clockwise, reversing any ring given the other way round.
§Errors
Returns a PolygonError naming the offending ring if the input is not
a simple polygon with holes. See Polygon’s invariants for the full
list of checks.
§Examples
use straight_skeleton::{Point, Polygon, PolygonError};
// A ring that crosses itself is rejected, not silently accepted.
let crossed = Polygon::from_outer(&[
Point::new(0, 0),
Point::new(10, 10),
Point::new(10, 0),
Point::new(0, 4),
]);
assert!(matches!(crossed, Err(PolygonError::SelfIntersection { .. })));Sourcepub fn from_outer(outer: &[Point]) -> Result<Self, PolygonError>
pub fn from_outer(outer: &[Point]) -> Result<Self, PolygonError>
Sourcepub fn vertex_count(&self) -> usize
pub fn vertex_count(&self) -> usize
Total number of vertices across all rings.
Sourcepub fn ring_count(&self) -> usize
pub fn ring_count(&self) -> usize
Number of rings: 1 (outer) plus one per hole.
Sourcepub fn hole_count(&self) -> usize
pub fn hole_count(&self) -> usize
Number of holes.
Sourcepub fn rings(&self) -> impl Iterator<Item = &[Point]> + '_
pub fn rings(&self) -> impl Iterator<Item = &[Point]> + '_
Iterates every ring’s vertices in order, outer ring first.
Sourcepub fn next_vertex(&self, v: VertexId) -> VertexId
pub fn next_vertex(&self, v: VertexId) -> VertexId
The vertex following v within its ring, wrapping at the ring’s end.
Sourcepub fn prev_vertex(&self, v: VertexId) -> VertexId
pub fn prev_vertex(&self, v: VertexId) -> VertexId
The vertex preceding v within its ring, wrapping at the ring’s start.
Sourcepub fn edge(&self, e: EdgeId) -> (Point, Point)
pub fn edge(&self, e: EdgeId) -> (Point, Point)
The endpoints of an edge, in direction order.
The polygon’s interior lies to the left of start -> end.
§Panics
Panics if e does not belong to this polygon.
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
Total number of edges, which equals the number of vertices.
Sourcepub fn vertex_ids(&self) -> impl Iterator<Item = VertexId> + '_
pub fn vertex_ids(&self) -> impl Iterator<Item = VertexId> + '_
Iterates every vertex id.
Sourcepub fn is_reflex(&self, v: VertexId) -> bool
pub fn is_reflex(&self, v: VertexId) -> bool
Whether the interior angle at v exceeds 180°, i.e. v is a reflex
(“notch”) corner.
Reflex vertices are the only ones that can trigger split events, so this drives the algorithm’s main branch.
Sourcepub fn signed_area2(&self) -> i64
pub fn signed_area2(&self) -> i64
Twice the signed area of the polygon: the outer ring’s area minus every hole’s. Always positive for a valid polygon.