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) => {
|
PartitionSvgPathKind::Stroke(stroke_width) => {
|
||||||
let mut temp_path_buffer = PathBuffer::new();
|
let mut temp_path_buffer = PathBuffer::new();
|
||||||
stroke::stroke(&mut temp_path_buffer, stream.into_iter(), stroke_width);
|
stroke::stroke(&mut temp_path_buffer, stream.into_iter(), stroke_width);
|
||||||
|
|
||||||
let stream = PathBufferStream::new(&temp_path_buffer);
|
let stream = PathBufferStream::new(&temp_path_buffer);
|
||||||
let stream = MonotonicPathSegmentStream::new(stream);
|
let stream = MonotonicPathSegmentStream::new(stream);
|
||||||
path_buffer.add_stream(stream)
|
path_buffer.add_stream(stream)
|
||||||
|
|
|
@ -54,11 +54,11 @@ impl Curve {
|
||||||
|
|
||||||
pub fn inflection_points(&self) -> (Option<f32>, Option<f32>) {
|
pub fn inflection_points(&self) -> (Option<f32>, Option<f32>) {
|
||||||
let inflection_point_x = Curve::inflection_point_x(self.endpoints[0].x,
|
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,
|
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)
|
(inflection_point_x, inflection_point_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ impl Curve {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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> {
|
-> Option<f32> {
|
||||||
let num = endpoint_x_0 - control_point_x;
|
let num = endpoint_x_0 - control_point_x;
|
||||||
let denom = endpoint_x_0 - 2.0 * control_point_x + endpoint_x_1;
|
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)) => {
|
Some(PathSegment::CurveTo(control_point, endpoint)) => {
|
||||||
let curve = Curve::new(&self.prev_point, &control_point, &endpoint);
|
let curve = Curve::new(&self.prev_point, &control_point, &endpoint);
|
||||||
|
self.prev_point = endpoint;
|
||||||
match curve.inflection_points() {
|
match curve.inflection_points() {
|
||||||
(None, None) => {
|
(None, None) => Some(PathSegment::CurveTo(control_point, endpoint)),
|
||||||
self.prev_point = endpoint;
|
|
||||||
Some(PathSegment::CurveTo(control_point, endpoint))
|
|
||||||
}
|
|
||||||
(Some(t), None) | (None, Some(t)) => {
|
(Some(t), None) | (None, Some(t)) => {
|
||||||
let (prev_curve, next_curve) = curve.subdivide(t);
|
let (prev_curve, next_curve) = curve.subdivide(t);
|
||||||
self.queue.push(next_curve.to_path_segment());
|
self.queue.push(next_curve.to_path_segment());
|
||||||
self.prev_point = prev_curve.endpoints[1];
|
|
||||||
Some(prev_curve.to_path_segment())
|
Some(prev_curve.to_path_segment())
|
||||||
}
|
}
|
||||||
(Some(mut t0), Some(mut t1)) => {
|
(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_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_1.to_path_segment());
|
||||||
self.queue.push(curve_2.to_path_segment());
|
self.queue.push(curve_2.to_path_segment());
|
||||||
|
|
||||||
self.prev_point = curve_0.endpoints[1];
|
|
||||||
Some(curve_0.to_path_segment())
|
Some(curve_0.to_path_segment())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue