pub struct Curve { /* private fields */ }Expand description
A B-spline curve: a parametric function that maps the domain [0, 1] into N-dimensional space.
The curve and its derivatives follow from
with the parameter u ∈ [0, 1], the derivative order k, the number of polygon segments n,
the degree p, the knot vector U of the k-th derivative (see Knots), the n + 1 − k
basis functions N of degree p − k, and the n + 1 − k control points P
of the k-th derivative (see ControlPoints).
The plot shows a cubic curve in red and its first, second, and third derivative in purple, blue, and teal.
Implementations§
Source§impl Curve
impl Curve
Sourcepub fn new(knots: Knots, control_points: ControlPoints) -> Result<Self>
pub fn new(knots: Knots, control_points: ControlPoints) -> Result<Self>
Returns a curve defined by the given knot vector and control points. The knot vector must be clamped and normalized to [0, 1], and its n + p + 2 knots need n + 1 control points with finite coordinates.
§Examples
use bsplines::{ControlPoints, Curve, Knots};
use nalgebra::dmatrix;
// Create a coordinate matrix containing five 3D points.
let control_points = ControlPoints::new(dmatrix![
// 1 2 3 4 5
-2.0,-2.0,-1.0, 0.5, 1.5; // x
-1.0, 0.0, 1.0, 1.0, 2.0; // y
0.0, 0.5, 1.5,-0.5,-1.0; // z
]);
let degree = 2;
let knots = Knots::uniform(degree, control_points.polygon_segments()).unwrap();
let curve = Curve::new(knots, control_points).unwrap();
println!("{:?}", curve.evaluate(0.5));Sourcepub fn with_uniform_knots(
control_points: ControlPoints,
degree: usize,
) -> Result<Self>
pub fn with_uniform_knots( control_points: ControlPoints, degree: usize, ) -> Result<Self>
Returns a curve of the given degree with the given control points on a clamped, uniform knot vector.
| 18 points. | A curve of degree 2 with the points as control points. |
|---|---|
§Examples
use bsplines::{ControlPoints, Curve};
use nalgebra::dmatrix;
let curve = Curve::with_uniform_knots(ControlPoints::new(dmatrix![-2.0,-1.0, 0.5, 1.5;]), 2).unwrap();Sourcepub fn interpolate(data: &DataPoints, degree: usize) -> Result<Self>
pub fn interpolate(data: &DataPoints, degree: usize) -> Result<Self>
Returns a curve of the given degree interpolating the data points, using equally spaced parameters and a uniform knot vector.
| 18 data points. | The curve of degree 2 that interpolates them. |
|---|---|
§Examples
use bsplines::{Curve, DataPoints};
use nalgebra::dmatrix;
let data = DataPoints::new(dmatrix![
1.0, 2.0, 3.0, 4.0;
1.0, 2.0, 3.0, 4.0;
]);
let curve = Curve::interpolate(&data, 2).unwrap();Sourcepub fn interpolate_with(
data: &DataPoints,
degree: usize,
parameter_method: ParameterMethod,
knot_method: KnotMethod,
) -> Result<Self>
pub fn interpolate_with( data: &DataPoints, degree: usize, parameter_method: ParameterMethod, knot_method: KnotMethod, ) -> Result<Self>
Returns a curve of the given degree interpolating the data points, with explicitly chosen parameter and knot generation methods.
Sourcepub fn fit<'a>(data: &'a DataPoints, degree: usize) -> FitBuilder<'a>
pub fn fit<'a>(data: &'a DataPoints, degree: usize) -> FitBuilder<'a>
Returns a builder for a least-squares fit of the data points with a curve of the given degree.
The plots fit curves of degree 2 with loose ends to 18 data points.
| 17 polygon segments. | 6 polygon segments. | 6 polygon segments, penalized with λ = 0.5 and κ = 2. |
|---|---|---|
§Examples
use bsplines::{Curve, DataPoints};
use nalgebra::dmatrix;
let data = DataPoints::new(dmatrix![
1.0, 2.0, 3.0, 4.0, 5.0;
1.0, 2.0, 3.0, 4.0, 5.0;
]);
let curve = Curve::fit(&data, 2).polygon_segments(3).loose_ends().build().unwrap();Sourcepub fn control_points(&self) -> &ControlPoints
pub fn control_points(&self) -> &ControlPoints
Returns the control points.
Sourcepub fn polygon_segments(&self) -> usize
pub fn polygon_segments(&self) -> usize
Returns the number of segments n of the control polygon.
Sourcepub fn evaluate_derivative(
&self,
u: f64,
derivative: usize,
) -> Result<DVector<f64>>
pub fn evaluate_derivative( &self, u: f64, derivative: usize, ) -> Result<DVector<f64>>
Evaluates the k-th derivative of the curve at the parameter u:
C⁽ᵏ⁾(u) = Σᵢ Nᵢ,ₚ₋ₖ(u) · Pᵢ⁽ᵏ⁾
with the basis functions N of degree p − k on the derivative knot vector and the control points P of the derivative curve, summed over the local polynomial segment.
Derivative orders beyond the degree return the zero vector, since all higher derivatives of a polynomial of degree p vanish.
Sourcepub fn reverse(&mut self) -> &mut Self
pub fn reverse(&mut self) -> &mut Self
Reverses the direction of the curve: the point at the parameter u moves to 1 − u.
| The curve. | The reversed curve. |
|---|---|
Sourcepub fn prepend(&mut self, other: &Self) -> Result<&mut Self>
pub fn prepend(&mut self, other: &Self) -> Result<&mut Self>
Prepends another curve: attaches the end of the other curve to the start of this curve
and keeps all derivatives continuous at the joint — see Curve::append.
§Examples
use approx::assert_relative_eq;
use bsplines::{ControlPoints, Curve, Points};
use nalgebra::dmatrix;
let mut curve = Curve::with_uniform_knots(ControlPoints::new(dmatrix![ 1.0, 2.0, 3.0;]), 2).unwrap();
let other = Curve::with_uniform_knots(ControlPoints::new(dmatrix![-3.0,-2.0,-1.0;]), 2).unwrap();
let merged = curve.prepend(&other).unwrap();
assert_relative_eq!(merged.control_points().matrix(), &dmatrix![-3.0,-2.0, 2.0, 3.0;], epsilon = f64::EPSILON.sqrt());Sourcepub fn prepend_constrained(
&mut self,
other: &Self,
constraints: Constraints,
) -> Result<&mut Self>
pub fn prepend_constrained( &mut self, other: &Self, constraints: Constraints, ) -> Result<&mut Self>
Prepends another curve like Curve::prepend, but keeps the points at the constrained
parameters fixed. The other curve is the left one, this curve is the right one.
Sourcepub fn append(&mut self, other: &Self) -> Result<&mut Self>
pub fn append(&mut self, other: &Self) -> Result<&mut Self>
Appends another curve: attaches the end of this curve to the start of the other curve
and keeps all derivatives continuous at the joint — see Tai2003. The merge moves the last
p control points of this curve and the first p control points of the other curve, and it
removes p control points in total.
| Two curves. | The merged curve. |
|---|---|
§Examples
use approx::assert_relative_eq;
use bsplines::{ControlPoints, Curve, Points};
use nalgebra::dmatrix;
let mut curve = Curve::with_uniform_knots(ControlPoints::new(dmatrix![-3.0,-2.0,-1.0;]), 2).unwrap();
let other = Curve::with_uniform_knots(ControlPoints::new(dmatrix![ 1.0, 2.0, 3.0;]), 2).unwrap();
let merged = curve.append(&other).unwrap();
assert_relative_eq!(merged.control_points().matrix(), &dmatrix![-3.0,-2.0, 2.0, 3.0;], epsilon = f64::EPSILON.sqrt());Sourcepub fn append_constrained(
&mut self,
other: &Self,
constraints: Constraints,
) -> Result<&mut Self>
pub fn append_constrained( &mut self, other: &Self, constraints: Constraints, ) -> Result<&mut Self>
Appends another curve like Curve::append, but keeps the points at the constrained
parameters fixed. This curve is the left one, the other curve is the right one.
§Examples
use approx::assert_relative_eq;
use bsplines::{Constraints, ControlPoints, Curve};
use nalgebra::dmatrix;
let mut curve = Curve::with_uniform_knots(ControlPoints::new(dmatrix![-2.0,-1.0,-0.5;]), 2).unwrap();
let other = Curve::with_uniform_knots(ControlPoints::new(dmatrix![ 0.5, 1.0, 2.0;]), 2).unwrap();
let end = curve.evaluate(1.0).unwrap();
// Keep the end of this curve fixed, so the joint at u = 0.5 stays at its old end point.
curve.append_constrained(&other, Constraints { left: vec![1.0], right: vec![] }).unwrap();
assert_relative_eq!(curve.evaluate(0.5).unwrap(), end, epsilon = f64::EPSILON.sqrt());Sourcepub fn split(&self, u: f64) -> Result<(Self, Self)>
pub fn split(&self, u: f64) -> Result<(Self, Self)>
Splits the curve into two independent curves at the parameter u,
normalizing both knot vectors to the domain [0, 1].
The parameter must lie in the domain interior (0, 1).
| The curve. | The two curves after the split at u = 1/2. |
|---|---|
Sourcepub fn insert_knot(&mut self, u: f64) -> Result<&mut Self>
pub fn insert_knot(&mut self, u: f64) -> Result<&mut Self>
Inserts a knot at the parameter u without changing the curve shape.
The parameter must lie in the domain interior (0, 1). Call it again to raise the multiplicity of u.
| The curve. | The curve after the insertion at u = 4/5. |
|---|---|
Sourcepub fn derivative_curve(&self, derivative: usize) -> Result<Self>
pub fn derivative_curve(&self, derivative: usize) -> Result<Self>
Returns the curve describing the k-th derivative of this curve.
The derivative order must not exceed the degree p.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Curve
impl RefUnwindSafe for Curve
impl Send for Curve
impl Sync for Curve
impl Unpin for Curve
impl UnsafeUnpin for Curve
impl UnwindSafe for Curve
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.