Fix de Casteljau subdivision when a curve has two inflection points
This commit is contained in:
parent
be1b100826
commit
88f1d3f108
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
match curve.inflection_points() {
|
||||
(None, None) => {
|
||||
self.prev_point = endpoint;
|
||||
Some(PathSegment::CurveTo(control_point, endpoint))
|
||||
}
|
||||
match curve.inflection_points() {
|
||||
(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())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue