1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use super::SplineOpts; pub fn get_curve_points(points: &[f64], opts: &SplineOpts) -> Vec<f64> { let SplineOpts { tension, num_of_segments, disallow_x_stepping_back, } = *opts; let mut pts: Vec<f64> = points.into(); let length = pts.len(); if length == 0 || length == 1 { return pts; } if pts.len() % 2 != 0 { pts.truncate(pts.len() - 1); } if pts.len() == 2 { return pts; } pts.insert(0, pts[1]); pts.insert(0, pts[1]); pts.push(pts[pts.len() - 2]); pts.push(pts[pts.len() - 2]); let mut result = Vec::with_capacity(pts.len() * num_of_segments as usize); let num_of_segments_f64 = f64::from(num_of_segments); let mut i = 2; while i < (pts.len() - 4) { for t in 0..=num_of_segments { let t1x = (pts[i + 2] - pts[i - 2]) * tension; let t2x = (pts[i + 4] - pts[i]) * tension; let t1y = (pts[i + 3] - pts[i - 1]) * tension; let t2y = (pts[i + 5] - pts[i + 1]) * tension; let st = f64::from(t) / num_of_segments_f64; let st_pow2 = st.powi(2); let st_pow3 = st.powi(3); let st_pow2x3 = 3.0 * st_pow2; let st_pow3x2 = 2.0 * st_pow3; let c1 = st_pow3x2 - st_pow2x3 + 1.0; let c2 = -st_pow3x2 + st_pow2x3; let c3 = st_pow3 - 2.0 * st_pow2 + st; let c4 = st_pow3 - st_pow2; let mut x = c1 * pts[i] + c2 * pts[i + 2] + c3 * t1x + c4 * t2x; let y = c1 * pts[i + 1] + c2 * pts[i + 3] + c3 * t1y + c4 * t2y; if disallow_x_stepping_back && result.len() >= 2 { let last_x = result[result.len() - 2]; if x < last_x { x = last_x; } } result.push(x); result.push(y); } i += 2; } result }