-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
pub fn fit_curve_cubic<Curve: BezierCurveFactory+BezierCurve>(points: &[Curve::Point], start_tangent: &Curve::Point, end_tangent: &Curve::Point, iterations: u32) -> Vec<Curve> {
if points.len() <= 2 {
// 2 points is a line (less than 2 points is an error here)
fit_line(&points[0], &points[1])
} else {
// Perform an initial estimate of the 't' values corresponding to the chords of the curve
let mut chords = chords_for_points(points);
// Use the least-squares method to fit against the initial set of chords
let mut curve = generate_bezier(points, &chords, start_tangent, end_tangent);
// Reparameterise the chords (which will probably be quite a bad estimate initially)
chords = reparameterize(points, &chords, &curve);
curve = generate_bezier(points, &chords, start_tangent, end_tangent);
// Estimate the error after the reparameterization
let (mut error, mut split_pos) = max_error_for_curve(points, &chords, &curve);
// Try iterating to improve the fit if we're not too far out
for _iteration in 1..iterations {
// Recompute the chords and the curve
chords = reparameterize(points, &chords, &curve);
curve = generate_bezier(points, &chords, start_tangent, end_tangent);
}
}
}Would something like this work? The code above is completely untested napkin code. Right now I'm using fit_cubic_curve and just raising the max_error until it returns only one curve, but I'd rather be able to give it a static number of iterations and do less spinning.
I'm willing to work on this myself if you give me the greenlight.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels