Add more fast paths to the clipper

This commit is contained in:
Patrick Walton 2019-02-01 18:25:48 -08:00
parent d08ff40cdf
commit ca3a8852a6
1 changed files with 37 additions and 0 deletions

View File

@ -276,6 +276,16 @@ trait ContourClipper where Self::Edge: TEdge {
fn contour_mut(&mut self) -> &mut Contour;
fn clip_against(&mut self, edge: Self::Edge) {
// Fast path to avoid allocation in the no-clip case.
match self.check_for_fast_clip(&edge) {
FastClipResult::SlowPath => {}
FastClipResult::AllInside => return,
FastClipResult::AllOutside => {
*self.contour_mut() = Contour::new();
return;
}
}
let input = mem::replace(self.contour_mut(), Contour::new());
for mut segment in input.iter() {
// Easy cases.
@ -334,6 +344,32 @@ trait ContourClipper where Self::Edge: TEdge {
contour.push_segment(*segment);
}
}
fn check_for_fast_clip(&mut self, edge: &Self::Edge) -> FastClipResult {
let mut result = None;
for segment in self.contour_mut().iter() {
let location = edge.trivially_test_segment(&segment);
match (result, location) {
(None, EdgeRelativeLocation::Outside) => {
result = Some(FastClipResult::AllOutside);
}
(None, EdgeRelativeLocation::Inside) => {
result = Some(FastClipResult::AllInside);
}
(Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside) |
(Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {}
(_, _) => return FastClipResult::SlowPath,
}
}
result.unwrap_or(FastClipResult::AllOutside)
}
}
#[derive(Clone, Copy)]
enum FastClipResult {
SlowPath,
AllInside,
AllOutside,
}
// General convex polygon clipping in 2D
@ -375,6 +411,7 @@ impl ContourPolygonClipper {
}
}
#[derive(PartialEq)]
enum EdgeRelativeLocation {
Intersecting,
Inside,