Skip to main content

Curve

Struct Curve 

Source
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

B-spline curve

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.

A cubic curve and its derivatives

Implementations§

Source§

impl Curve

Source

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));
Source

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();
Source

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();
Source

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.

Source

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();
Source

pub fn knots(&self) -> &Knots

Returns the knot vector.

Source

pub fn control_points(&self) -> &ControlPoints

Returns the control points.

Source

pub fn degree(&self) -> usize

Returns the degree p of the curve.

Source

pub fn polygon_segments(&self) -> usize

Returns the number of segments n of the control polygon.

Source

pub fn dimension(&self) -> usize

Returns the dimension of the curve.

Source

pub fn evaluate(&self, u: f64) -> Result<DVector<f64>>

Evaluates the curve at the parameter u.

Source

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.

Source

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.
Source

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());
Source

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.

Source

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());
Source

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());
Source

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.
Source

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.
Source

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§

Source§

impl Clone for Curve

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Curve

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.