Fix de Casteljau subdivision when a curve has two inflection points

This commit is contained in:
Patrick Walton 2017-09-22 13:40:41 -07:00
parent be1b100826
commit 88f1d3f108
3 changed files with 9 additions and 12 deletions

View File

@ -506,6 +506,7 @@ fn partition_svg_paths(request: Json<PartitionSvgPathsRequest>)
PartitionSvgPathKind::Stroke(stroke_width) => {
let mut temp_path_buffer = PathBuffer::new();
stroke::stroke(&mut temp_path_buffer, stream.into_iter(), stroke_width);
let stream = PathBufferStream::new(&temp_path_buffer);
let stream = MonotonicPathSegmentStream::new(stream);
path_buffer.add_stream(stream)

View File

@ -54,11 +54,11 @@ impl Curve {
pub fn inflection_points(&self) -> (Option<f32>, Option<f32>) {
let inflection_point_x = Curve::inflection_point_x(self.endpoints[0].x,
self.endpoints[1].x,
self.control_point.x);
self.control_point.x,
self.endpoints[1].x);
let inflection_point_y = Curve::inflection_point_x(self.endpoints[0].y,
self.endpoints[1].y,
self.control_point.y);
self.control_point.y,
self.endpoints[1].y);
(inflection_point_x, inflection_point_y)
}
@ -68,7 +68,7 @@ impl Curve {
}
#[inline]
fn inflection_point_x(endpoint_x_0: f32, endpoint_x_1: f32, control_point_x: f32)
fn inflection_point_x(endpoint_x_0: f32, control_point_x: f32, endpoint_x_1: f32)
-> Option<f32> {
let num = endpoint_x_0 - control_point_x;
let denom = endpoint_x_0 - 2.0 * control_point_x + endpoint_x_1;

View File

@ -52,15 +52,12 @@ impl<I> Iterator for MonotonicPathSegmentStream<I> where I: Iterator<Item = Path
}
Some(PathSegment::CurveTo(control_point, endpoint)) => {
let curve = Curve::new(&self.prev_point, &control_point, &endpoint);
self.prev_point = endpoint;
match curve.inflection_points() {
(None, None) => {
self.prev_point = endpoint;
Some(PathSegment::CurveTo(control_point, endpoint))
}
(None, None) => Some(PathSegment::CurveTo(control_point, endpoint)),
(Some(t), None) | (None, Some(t)) => {
let (prev_curve, next_curve) = curve.subdivide(t);
self.queue.push(next_curve.to_path_segment());
self.prev_point = prev_curve.endpoints[1];
Some(prev_curve.to_path_segment())
}
(Some(mut t0), Some(mut t1)) => {
@ -69,11 +66,10 @@ impl<I> Iterator for MonotonicPathSegmentStream<I> where I: Iterator<Item = Path
}
let (curve_0, curve_12) = curve.subdivide(t0);
let (curve_1, curve_2) = curve_12.subdivide(t1);
let (curve_1, curve_2) = curve_12.subdivide((t1 - t0) / (1.0 - t0));
self.queue.push(curve_1.to_path_segment());
self.queue.push(curve_2.to_path_segment());
self.prev_point = curve_0.endpoints[1];
Some(curve_0.to_path_segment())
}
}