Struct bevy::prelude::CubicNurbs
pub struct CubicNurbs<P>where
P: VectorSpace,{ /* private fields */ }
Expand description
Non-uniform Rational B-Splines (NURBS) are a powerful generalization of the CubicBSpline
which can
represent a much more diverse class of curves (like perfect circles and ellipses).
§Non-uniformity
The ‘NU’ part of NURBS stands for “Non-Uniform”. This has to do with a parameter called ‘knots’. The knots are a non-decreasing sequence of floating point numbers. The first and last three pairs of knots control the behavior of the curve as it approaches its endpoints. The intermediate pairs each control the length of one segment of the curve. Multiple repeated knot values are called “knot multiplicity”. Knot multiplicity in the intermediate knots causes a “zero-length” segment, and can create sharp corners.
§Rationality
The ‘R’ part of NURBS stands for “Rational”. This has to do with NURBS allowing each control point to be assigned a weighting, which controls how much it affects the curve compared to the other points.
§Interpolation
The curve will not pass through the control points except where a knot has multiplicity four.
§Tangency
Tangents are automatically computed based on the position of control points.
§Continuity
When there is no knot multiplicity, the curve is C2 continuous, meaning it has no holes or jumps and the
tangent vector changes smoothly along the entire curve length. Like the CubicBSpline
, the acceleration
continuity makes it useful for camera paths. Knot multiplicity of 2 in intermediate knots reduces the
continuity to C2, and knot multiplicity of 3 reduces the continuity to C0. The curve is always at least
C0, meaning it has no jumps or holes.
§Usage
let points = [
vec2(-1.0, -20.0),
vec2(3.0, 2.0),
vec2(5.0, 3.0),
vec2(9.0, 8.0),
];
let weights = [1.0, 1.0, 2.0, 1.0];
let knots = [0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 5.0];
let nurbs = CubicNurbs::new(points, Some(weights), Some(knots))
.expect("NURBS construction failed!")
.to_curve();
let positions: Vec<_> = nurbs.iter_positions(100).collect();
Implementations§
§impl<P> CubicNurbs<P>where
P: VectorSpace,
impl<P> CubicNurbs<P>where
P: VectorSpace,
pub fn new(
control_points: impl Into<Vec<P>>,
weights: Option<impl Into<Vec<f32>>>,
knots: Option<impl Into<Vec<f32>>>
) -> Result<CubicNurbs<P>, CubicNurbsError>
pub fn new( control_points: impl Into<Vec<P>>, weights: Option<impl Into<Vec<f32>>>, knots: Option<impl Into<Vec<f32>>> ) -> Result<CubicNurbs<P>, CubicNurbsError>
Build a Non-Uniform Rational B-Spline.
If provided, weights must be the same length as the control points. Defaults to equal weights.
If provided, the number of knots must be n + 4 elements, where n is the amount of control
points. Defaults to open uniform knots: Self::open_uniform_knots
. Knots cannot
all be equal.
At least 4 points must be provided, otherwise an error will be returned.
pub fn uniform_knots(control_points: usize) -> Option<Vec<f32>>
pub fn uniform_knots(control_points: usize) -> Option<Vec<f32>>
Generates uniform knots that will generate the same curve as CubicBSpline
.
“Uniform” means that the difference between two subsequent knots is the same.
Will return None
if there are less than 4 control points.
pub fn open_uniform_knots(control_points: usize) -> Option<Vec<f32>>
pub fn open_uniform_knots(control_points: usize) -> Option<Vec<f32>>
Generates open uniform knots, which makes the ends of the curve pass through the start and end points.
The start and end knots have multiplicity 4, and intermediate knots have multiplicity 0 and difference of 1.
Will return None
if there are less than 4 control points.
Trait Implementations§
§impl<P> RationalGenerator<P> for CubicNurbs<P>where
P: VectorSpace,
impl<P> RationalGenerator<P> for CubicNurbs<P>where
P: VectorSpace,
§fn to_curve(&self) -> RationalCurve<P>
fn to_curve(&self) -> RationalCurve<P>
RationalCurve
by computing the interpolation coefficients for each curve segment.Auto Trait Implementations§
impl<P> Freeze for CubicNurbs<P>
impl<P> RefUnwindSafe for CubicNurbs<P>where
P: RefUnwindSafe,
impl<P> Send for CubicNurbs<P>where
P: Send,
impl<P> Sync for CubicNurbs<P>where
P: Sync,
impl<P> Unpin for CubicNurbs<P>where
P: Unpin,
impl<P> UnwindSafe for CubicNurbs<P>where
P: UnwindSafe,
Blanket Implementations§
§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.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
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more