mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-05 16:48:12 +08:00
Implement bezier local_extrema function (#693)
* Implement backend of extrema in bezier-rs * Added extrema frontend * Added extrema interface * Wrapped extrema in filter function to remove points not on the curve * Saved intermediate results while computing extrema * Fixed extrema bug when a in cubic formula is 0 * Removed extra prints * Fixed quadratic extrema regression * Moved helper functions to utils file * Fixed bug in solve linear * Stylistic changes per review * Sentence comments Co-authored-by: Linda Zheng <thelindazheng@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Linda Zheng
Keavon Chambers
parent
3ab47418d2
commit
c343aaa3ab
@@ -20,8 +20,8 @@ pub fn compute_abc_for_quadratic_through_points(start_point: DVec2, point_on_cur
|
||||
compute_abc_through_points(start_point, point_on_curve, end_point, t_squared, squared_one_minus_t)
|
||||
}
|
||||
|
||||
/// Compute a, b, and c for a cubic curve that fits the start, end and point on curve at `t`.
|
||||
/// The definition for the a, b, c points are defined in [the projection identity section](https://pomax.github.io/bezierinfo/#abc) of Pomax's bezier curve primer.
|
||||
/// Compute `a`, `b`, and `c` for a cubic curve that fits the start, end and point on curve at `t`.
|
||||
/// The definition for the `a`, `b`, `c` points are defined in [the projection identity section](https://pomax.github.io/bezierinfo/#abc) of Pomax's bezier curve primer.
|
||||
pub fn compute_abc_for_cubic_through_points(start_point: DVec2, point_on_curve: DVec2, end_point: DVec2, t: f64) -> [DVec2; 3] {
|
||||
let t_cubed = t * t * t;
|
||||
let one_minus_t = 1. - t;
|
||||
@@ -37,3 +37,30 @@ pub fn get_closest_point_in_lut(lut: &[DVec2], point: DVec2) -> (i32, f64) {
|
||||
.min_by(|x, y| (&(x.1)).partial_cmp(&(y.1)).unwrap())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Find the roots of the linear equation `ax + b`
|
||||
pub fn solve_linear(a: f64, b: f64) -> Vec<f64> {
|
||||
let mut roots = Vec::new();
|
||||
if a != 0. {
|
||||
roots.push(-b / a);
|
||||
}
|
||||
roots
|
||||
}
|
||||
|
||||
/// Find the roots of the linear equation `ax^2 + bx + c`
|
||||
/// Precompute the `discriminant` (`b^2 - 4ac`) and `two_times_a` arguments prior to calling this function for efficiency purposes
|
||||
pub fn solve_quadratic(discriminant: f64, two_times_a: f64, b: f64, c: f64) -> Vec<f64> {
|
||||
let mut roots = Vec::new();
|
||||
if two_times_a != 0. {
|
||||
if discriminant > 0. {
|
||||
let root_discriminant = discriminant.sqrt();
|
||||
roots.push((-b + root_discriminant) / (two_times_a));
|
||||
roots.push((-b - root_discriminant) / (two_times_a));
|
||||
} else if discriminant == 0. {
|
||||
roots.push(-b / (two_times_a));
|
||||
}
|
||||
} else {
|
||||
roots = solve_linear(b, c);
|
||||
}
|
||||
roots
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user