pub struct Node {
pub position: Point,
pub exact: [f32; 2],
pub offset: f32,
pub kind: NodeKind,
pub sources: Vec<EdgeId>,
}Expand description
A vertex of the skeleton graph.
§Examples
use straight_skeleton::{skeleton, NodeKind, Point, Polygon};
let square = Polygon::from_outer(&[
Point::new(0, 0), Point::new(10, 0), Point::new(10, 10), Point::new(0, 10),
])?;
let skel = skeleton(&square)?;
// Every input vertex gets a boundary node at offset 0.
let boundary: Vec<_> = skel.nodes().iter().filter(|n| n.is_boundary()).collect();
assert_eq!(boundary.len(), 4);
assert!(boundary.iter().all(|n| n.offset == 0.0));Fields§
§position: PointThe node’s position, rounded to the integer lattice.
Skeleton nodes are generally irrational even for integer input, so this
is the nearest lattice point. Use Node::exact when the rounding
matters.
exact: [f32; 2]The node’s unrounded position.
The algorithm computes in f32 throughout, so this is the value it
actually arrived at, not a narrowing of something wider.
offset: f32How far the wavefront had travelled when this node was created.
For a plain skeleton, this is the node’s distance to the supporting
line of each of its Node::sources. It is the node’s height on a
roof, and the offset at which the node appears on an offset curve.
For a skeleton_constrained, it is the wavefront’s time, which is
no longer the same thing: an edge that stopped at limit stays limit
away however long the wavefront runs on. The distance to a source edge
e’s line is min(offset, limit_e).
kind: NodeKindWhat produced this node.
sources: Vec<EdgeId>The input edges whose wavefronts arrived here together.
Always at least 2 entries, and 3 or more where several skeleton arcs
meet. Each one’s supporting line is Node::offset away (see that
field for the constrained case).
§This is not quite “nearest”
For a convex polygon these really are the nearest input edges, since there the straight skeleton coincides with the medial axis.
Elsewhere they may not be, and the difference is the definition of a straight skeleton rather than a wrinkle in this implementation. A straight skeleton bisects edges’ infinite supporting lines, which is what keeps every arc straight. A medial axis bisects the nearest features, and so grows parabolic arcs around reflex vertices. Around a reflex corner the two part company: a plus-shape’s centre is at offset 5 from the four arms’ walls, but the nearest input feature is a reflex corner 7.07 away.
So read sources as “the input edges whose faces meet here” — which is
the useful notion anyway, and the one a roof needs. See Arc::sources.
Implementations§
Source§impl Node
impl Node
Sourcepub fn is_boundary(&self) -> bool
pub fn is_boundary(&self) -> bool
Whether this node lies on the input boundary.
Sourcepub fn input_vertex(&self) -> Option<VertexId>
pub fn input_vertex(&self) -> Option<VertexId>
The input vertex this node sits on, if it is a boundary node.