pub fn spline(points: Vec<impl Into<glam::DVec2>>, style: PathStyle) -> Self {
		let mut path = kurbo::BezPath::new();

		// Creating a bezier spline is only necessary for 3 or more points.
		// For 2 given points a line segment is created instead.
		if points.len() > 2 {
			let points: Vec<_> = points.into_iter().map(|v| v.into()).map(|v: DVec2| kurbo::Vec2 { x: v.x, y: v.y }).collect();

			// Number of bezier segments
			let n = points.len() - 1;

			// Control points for each bezier segment
			let mut p1 = vec![kurbo::Vec2::ZERO; n];
			let mut p2 = vec![kurbo::Vec2::ZERO; n];

			// Tri-diagonal matrix coefficients a, b and c (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm)
			let mut a = vec![1.0; n];
			a[0] = 0.0;
			a[n - 1] = 2.0;

			let mut b = vec![4.0; n];
			b[0] = 2.0;
			b[n - 1] = 7.0;

			let mut c = vec![1.0; n];
			c[n - 1] = 0.0;

			let mut r: Vec<_> = (0..n).map(|i| 4.0 * points[i] + 2.0 * points[i + 1]).collect();
			r[0] = points[0] + (2.0 * points[1]);
			r[n - 1] = 8.0 * points[n - 1] + points[n];

			// Solve with Thomas algorithm (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm)
			for i in 1..n {
				let m = a[i] / b[i - 1];
				b[i] -= m * c[i - 1];
				let last_iteration_r = r[i - 1];
				r[i] -= m * last_iteration_r;
			}

			// Determine first control point for each segment
			p1[n - 1] = r[n - 1] / b[n - 1];
			for i in (0..n - 1).rev() {
				p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
			}

			// Determine second control point per segment from first
			for i in 0..n - 1 {
				p2[i] = 2.0 * points[i + 1] - p1[i + 1];
			}
			p2[n - 1] = 0.5 * (points[n] + p1[n - 1]);

			// Create bezier path from given points and computed control points
			points.into_iter().enumerate().for_each(|(i, p)| {
				if i == 0 {
					path.move_to(p.to_point())
				} else {
					path.curve_to(p1[i - 1].to_point(), p2[i - 1].to_point(), p.to_point())
				}
			});
		} else {
			points
				.into_iter()
				.map(|v| v.into())
				.map(|v: DVec2| kurbo::Point { x: v.x, y: v.y })
				.enumerate()
				.for_each(|(i, p)| if i == 0 { path.move_to(p) } else { path.line_to(p) });
		}

		Self {
			path,
			style,
			render_index: 0,
			closed: false,
		}
	}
/// Creates a smooth bezier spline that passes through all given points.
/// The algorithm used in this implementation is described here: <https://www.particleincell.com/2012/bezier-splines/>
Creates a smooth bezier spline that passes through all given points.
The algorithm used in this implementation is described here.
Creates a smooth bezier spline that passes through all given points . The algorithm used in this implementation is described here .
pub fn spline(points: Vec<impl Into<glam::DVec2>>, style: PathStyle) -> Self {
		let mut path = kurbo::BezPath::new();
		// Creating a bezier spline is only necessary for 3 or more points.
		// For 2 given points a line segment is created instead.
		if points.len() > 2 {
			let points: Vec<_> = points.into_iter().map(|v| v.into()).map(|v: DVec2| kurbo::Vec2 { x: v.x, y: v.y }).collect();
			// Number of bezier segments
			let n = points.len() - 1;
			// Control points for each bezier segment
			let mut p1 = vec![kurbo::Vec2::ZERO; n];
			let mut p2 = vec![kurbo::Vec2::ZERO; n];
			// Tri-diagonal matrix coefficients a, b and c (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm)
			let mut a = vec![1.0; n];
			a[0] = 0.0;
			a[n - 1] = 2.0;
			let mut b = vec![4.0; n];
			b[0] = 2.0;
			b[n - 1] = 7.0;
			let mut c = vec![1.0; n];
			c[n - 1] = 0.0;
			let mut r: Vec<_> = (0..n).map(|i| 4.0 * points[i] + 2.0 * points[i + 1]).collect();
			r[0] = points[0] + (2.0 * points[1]);
			r[n - 1] = 8.0 * points[n - 1] + points[n];
			// Solve with Thomas algorithm (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm)
			for i in 1..n {
				let m = a[i] / b[i - 1];
				b[i] -= m * c[i - 1];
				let last_iteration_r = r[i - 1];
				r[i] -= m * last_iteration_r;
			}
			// Determine first control point for each segment
			p1[n - 1] = r[n - 1] / b[n - 1];
			for i in (0..n - 1).rev() {
				p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
			}
			// Determine second control point per segment from first
			for i in 0..n - 1 {
				p2[i] = 2.0 * points[i + 1] - p1[i + 1];
			}
			p2[n - 1] = 0.5 * (points[n] + p1[n - 1]);
			// Create bezier path from given points and computed control points
			points.into_iter().enumerate().for_each(|(i, p)| {
				if i == 0 {
					path.move_to(p.to_point())
				} else {
					path.curve_to(p1[i - 1].to_point(), p2[i - 1].to_point(), p.to_point())
				}
			});
		} else {
			points
				.into_iter()
				.map(|v| v.into())
				.map(|v: DVec2| kurbo::Point { x: v.x, y: v.y })
				.enumerate()
				.for_each(|(i, p)| if i == 0 { path.move_to(p) } else { path.line_to(p) });
		}
		Self {
			path,
			style,
			render_index: 0,
			closed: false,
		}
	}
pub fn spline ( points : Vec < impl Into < glam :: DVec2 > > , style : PathStyle ) -> Self { let mut path = kurbo :: BezPath :: new ( ) ; // Creating a bezier spline is only necessary for 3 or more points. // For 2 given points a line segment is created instead. if points . len ( ) > 2 { let points : Vec < _ > = points . into_iter ( ) . map ( | v | v . into ( ) ) . map ( | v : DVec2 | kurbo :: Vec2 { x : v . x , y : v . y } ) . collect ( ) ; // Number of bezier segments let n = points . len ( ) - 1 ; // Control points for each bezier segment let mut p1 = vec ! [ kurbo Vec2 ZERO n ] ; let mut p2 = vec ! [ kurbo Vec2 ZERO n ] ; // Tri-diagonal matrix coefficients a, b and c (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm) let mut a = vec ! [ 1.0 n ] ; a [ 0 ] = 0.0 ; a [ n - 1 ] = 2.0 ; let mut b = vec ! [ 4.0 n ] ; b [ 0 ] = 2.0 ; b [ n - 1 ] = 7.0 ; let mut c = vec ! [ 1.0 n ] ; c [ n - 1 ] = 0.0 ; let mut r : Vec < _ > = ( 0 .. n ) . map ( | i | 4.0 * points [ i ] + 2.0 * points [ i + 1 ] ) . collect ( ) ; r [ 0 ] = points [ 0 ] + ( 2.0 * points [ 1 ] ) ; r [ n - 1 ] = 8.0 * points [ n - 1 ] + points [ n ] ; // Solve with Thomas algorithm (see https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm) for i in 1 .. n { let m = a [ i ] / b [ i - 1 ] ; b [ i ] -= m * c [ i - 1 ] ; let last_iteration_r = r [ i - 1 ] ; r [ i ] -= m * last_iteration_r ; } // Determine first control point for each segment p1 [ n - 1 ] = r [ n - 1 ] / b [ n - 1 ] ; for i in ( 0 .. n - 1 ) . rev ( ) { p1 [ i ] = ( r [ i ] - c [ i ] * p1 [ i + 1 ] ) / b [ i ] ; } // Determine second control point per segment from first for i in 0 .. n - 1 { p2 [ i ] = 2.0 * points [ i + 1 ] - p1 [ i + 1 ] ; } p2 [ n - 1 ] = 0.5 * ( points [ n ] + p1 [ n - 1 ] ) ; // Create bezier path from given points and computed control points points . into_iter ( ) . enumerate ( ) . for_each ( | ( i , p ) | { if i == 0 { path . move_to ( p . to_point ( ) ) } else { path . curve_to ( p1 [ i - 1 ] . to_point ( ) , p2 [ i - 1 ] . to_point ( ) , p . to_point ( ) ) } } ) ; } else { points . into_iter ( ) . map ( | v | v . into ( ) ) . map ( | v : DVec2 | kurbo :: Point { x : v . x , y : v . y } ) . enumerate ( ) . for_each ( | ( i , p ) | if i == 0 { path . move_to ( p ) } else { path . line_to ( p ) } ) ; } Self { path , style , render_index : 0 , closed : false , } }
Creates a smooth bezier spline that passes through all given points.
Creates a smooth bezier spline that passes through all given points .
points
Vec<impl Into<glam::DVec2>>
style
PathStyle
points
Vec<impl Into<glam::DVec2>>
style
PathStyle