Skip to content

Commit

Permalink
Merge pull request #314 from linebender/stroke_nan
Browse files Browse the repository at this point in the history
Suppress cusps at endpoints of stroke
  • Loading branch information
raphlinus authored Oct 18, 2023
2 parents c7cb529 + 4d9db49 commit 6d04edd
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion src/stroke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,10 @@ impl StrokeCtx {
let c1 = 2.0 * p[2] - 4.0 * p[1] + 2.0 * p[0];
let c2 = p[3] - 3.0 * p[2] + 3.0 * p[1] - p[0];
let roots = solve_quadratic(c0, c1, c2);
// discard cusps right at endpoints
const EPSILON: f64 = 1e-12;
for t in roots {
if t > 0.0 && t < 1.0 {
if t > EPSILON && t < 1.0 - EPSILON {
let mt = 1.0 - t;
let z = mt * (mt * mt * p[0] + 3.0 * t * (mt * p[1] + t * p[2])) + t * t * t * p[3];
let p = ref_pt + z * ref_vec;
Expand Down Expand Up @@ -762,3 +764,25 @@ impl<'a, T: Iterator<Item = PathEl>> DashIterator<'a, T> {
self.is_active = self.init_is_active;
}
}

#[cfg(test)]
mod tests {
use crate::{stroke, CubicBez, Shape, Stroke};

// A degenerate stroke with a cusp at the endpoint.
#[test]
fn pathological_stroke() {
let curve = CubicBez::new(
(602.469, 286.585),
(641.975, 286.585),
(562.963, 286.585),
(562.963, 286.585),
);
let path = curve.into_path(0.1);
let stroke_style = Stroke::new(1.);
let stroked = stroke(path, &stroke_style, &Default::default(), 0.001);
for el in stroked.elements() {
assert!(el.is_finite());
}
}
}

0 comments on commit 6d04edd

Please sign in to comment.