flo_curves/bezier/path/graph_path/
edge.rs1use super::{GraphPath, GraphEdgeRef, GraphEdge, GraphPathEdge, GraphPathEdgeKind};
2use crate::bezier::curve::*;
3use crate::bezier::bounds::*;
4use crate::geo::*;
5
6use std::fmt;
7use std::cell::*;
8
9impl<Point: Coordinate, Label> GraphPathEdge<Point, Label> {
10 #[inline]
14 pub (crate) fn new(kind: GraphPathEdgeKind, (cp1, cp2): (Point, Point), end_idx: usize, label: Label, following_edge_idx: usize) -> GraphPathEdge<Point, Label> {
15 GraphPathEdge {
16 label, kind, cp1, cp2, end_idx, following_edge_idx, bbox: RefCell::new(None)
17 }
18 }
19
20 #[inline]
24 pub (crate) fn invalidate_cache(&self) {
25 (*self.bbox.borrow_mut()) = None;
26 }
27}
28
29impl<'a, Point: 'a, Label: 'a+Copy> GraphEdge<'a, Point, Label> {
30 #[inline]
34 pub (crate) fn new(graph: &'a GraphPath<Point, Label>, edge: GraphEdgeRef) -> GraphEdge<'a, Point, Label> {
35 test_assert!(edge.start_idx < graph.points.len());
36 test_assert!(edge.edge_idx < graph.points[edge.start_idx].forward_edges.len());
37
38 GraphEdge {
39 graph: graph,
40 edge: edge
41 }
42 }
43
44 #[inline]
48 pub fn is_reversed(&self) -> bool {
49 self.edge.reverse
50 }
51
52 #[inline]
56 fn edge(&self) -> &GraphPathEdge<Point, Label> {
57 &self.graph.points[self.edge.start_idx].forward_edges[self.edge.edge_idx]
58 }
59
60 pub fn kind(&self) -> GraphPathEdgeKind {
64 self.edge().kind
65 }
66
67 #[inline]
71 pub fn start_point_index(&self) -> usize {
72 if self.edge.reverse {
73 self.edge().end_idx
74 } else {
75 self.edge.start_idx
76 }
77 }
78
79 #[inline]
83 pub fn end_point_index(&self) -> usize {
84 if self.edge.reverse {
85 self.edge.start_idx
86 } else {
87 self.edge().end_idx
88 }
89 }
90
91 #[inline]
95 pub fn label(&self) -> Label {
96 self.edge().label
97 }
98}
99
100impl<'a, Point: 'a+Coordinate, Label: 'a> Geo for GraphEdge<'a, Point, Label> {
101 type Point = Point;
102}
103
104impl<'a, Point: 'a+Coordinate, Label: 'a+Copy> BezierCurve for GraphEdge<'a, Point, Label> {
105 #[inline]
109 fn start_point(&self) -> Self::Point {
110 self.graph.points[self.start_point_index()].position
111 }
112
113 #[inline]
117 fn end_point(&self) -> Self::Point {
118 self.graph.points[self.end_point_index()].position
119 }
120
121 #[inline]
125 fn control_points(&self) -> (Self::Point, Self::Point) {
126 let edge = self.edge();
127
128 if self.edge.reverse {
129 (edge.cp2, edge.cp1)
130 } else {
131 (edge.cp1, edge.cp2)
132 }
133 }
134
135 #[inline]
141 fn fast_bounding_box<Bounds: BoundingBox<Point=Self::Point>>(&self) -> Bounds {
142 let edge = self.edge();
143
144 let mut bbox = edge.bbox.borrow_mut();
145
146 if let Some((ref min, ref max)) = *bbox {
147 Bounds::from_min_max(*min, *max)
148 } else {
149 let start = self.graph.points[self.edge.start_idx].position;
150 let end = self.graph.points[edge.end_idx].position;
151 let control_points = (edge.cp1, edge.cp2);
152
153 let min = Self::Point::from_smallest_components(start, end);
154 let min = Self::Point::from_smallest_components(min, control_points.0);
155 let min = Self::Point::from_smallest_components(min, control_points.1);
156
157 let max = Self::Point::from_biggest_components(start, end);
158 let max = Self::Point::from_biggest_components(max, control_points.0);
159 let max = Self::Point::from_biggest_components(max, control_points.1);
160
161 let bounds = Bounds::from_min_max(min, max);
162
163 *bbox = Some((bounds.min(), bounds.max()));
164 bounds
165 }
166 }
167
168 #[inline]
172 fn bounding_box<Bounds: BoundingBox<Point=Self::Point>>(&self) -> Bounds {
173 let edge = self.edge();
174
175 let start = self.graph.points[self.edge.start_idx].position;
176 let end = self.graph.points[edge.end_idx].position;
177 let (cp1, cp2) = (edge.cp1, edge.cp2);
178
179 let bounds: Bounds = bounding_box4(start, cp1, cp2, end);
180
181 bounds
182 }
183}
184
185impl<'a, Point: 'a+Coordinate, Label: 'a+Copy> HasBoundingBox for GraphEdge<'a, Point, Label> {
186 #[inline]
187 fn get_bounding_box<Bounds: BoundingBox<Point=Self::Point>>(&self) -> Bounds {
188 self.fast_bounding_box()
189 }
190}
191
192impl<'a, Point: fmt::Debug, Label: 'a+Copy> fmt::Debug for GraphEdge<'a, Point, Label> {
193 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
194 write!(f, "{:?}: {:?} -> {:?} ({:?} -> {:?} ({:?}, {:?}))", self.kind(), self.edge.start_idx, self.edge().end_idx, self.graph.points[self.edge.start_idx].position, self.graph.points[self.edge().end_idx].position, self.edge().cp1, self.edge().cp2)
195 }
196}