Don't give up so quickly when performing Newton-Raphson
This commit is contained in:
parent
5393f63738
commit
410d2aa6cd
|
@ -83,17 +83,17 @@ pub fn solve_line_y_for_x(x: f32, a: &Point2D<f32>, b: &Point2D<f32>) -> f32 {
|
|||
a.lerp(*b, (x - a.x) / (b.x - a.x)).y
|
||||
}
|
||||
|
||||
fn newton_raphson<F, DFDX>(f: F, dfdx: DFDX, mut x_guess: f32) -> Option<f32>
|
||||
fn newton_raphson<F, DFDX>(f: F, dfdx: DFDX, mut x_guess: f32) -> f32
|
||||
where F: Fn(f32) -> f32, DFDX: Fn(f32) -> f32 {
|
||||
for _ in 0..NEWTON_RAPHSON_ITERATIONS {
|
||||
let y = f(x_guess);
|
||||
if y.approx_eq(&0.0) {
|
||||
return Some(x_guess)
|
||||
break
|
||||
}
|
||||
let yy = dfdx(x_guess);
|
||||
x_guess -= y / yy
|
||||
}
|
||||
None
|
||||
x_guess
|
||||
}
|
||||
|
||||
pub fn solve_cubic_bezier_t_for_x(x: f32,
|
||||
|
@ -101,7 +101,7 @@ pub fn solve_cubic_bezier_t_for_x(x: f32,
|
|||
p1: &Point2D<f32>,
|
||||
p2: &Point2D<f32>,
|
||||
p3: &Point2D<f32>)
|
||||
-> Option<f32> {
|
||||
-> f32 {
|
||||
newton_raphson(|t| sample_cubic_bezier(t, p0, p1, p2, p3).x - x,
|
||||
|t| sample_cubic_bezier_deriv(t, p0, p1, p2, p3).x,
|
||||
0.5)
|
||||
|
@ -112,6 +112,6 @@ pub fn solve_cubic_bezier_y_for_x(x: f32,
|
|||
p1: &Point2D<f32>,
|
||||
p2: &Point2D<f32>,
|
||||
p3: &Point2D<f32>)
|
||||
-> Option<f32> {
|
||||
solve_cubic_bezier_t_for_x(x, p0, p1, p2, p3).map(|t| sample_cubic_bezier(t, p0, p1, p2, p3).y)
|
||||
-> f32 {
|
||||
sample_cubic_bezier(solve_cubic_bezier_t_for_x(x, p0, p1, p2, p3), p0, p1, p2, p3).y
|
||||
}
|
||||
|
|
|
@ -369,13 +369,12 @@ impl<'a> Partitioner<'a> {
|
|||
(x - prev_endpoint.position.x) / x_vector
|
||||
}
|
||||
Some(control_points_index) => {
|
||||
// FIXME(pcwalton): Is `unwrap_or(0.0)` sensible?
|
||||
let control_points = &self.control_points[control_points_index as usize];
|
||||
geometry::solve_cubic_bezier_t_for_x(x,
|
||||
&prev_endpoint.position,
|
||||
&control_points.point1,
|
||||
&control_points.point2,
|
||||
&next_endpoint.position).unwrap_or(0.0)
|
||||
&next_endpoint.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,12 +413,11 @@ impl<'a> Partitioner<'a> {
|
|||
let control_points_index = self.control_points_index(next_endpoint_index)
|
||||
.expect("Edge not a cubic bezier!");
|
||||
let control_points = &self.control_points[control_points_index as usize];
|
||||
// FIXME(pcwalton): Is `.unwrap_or(0.0)` sensible?
|
||||
geometry::solve_cubic_bezier_y_for_x(x,
|
||||
&prev_endpoint.position,
|
||||
&control_points.point1,
|
||||
&control_points.point2,
|
||||
&next_endpoint.position).unwrap_or(0.0)
|
||||
&next_endpoint.position)
|
||||
}
|
||||
|
||||
fn control_points_index(&self, next_endpoint_index: u32) -> Option<u32> {
|
||||
|
|
Loading…
Reference in New Issue