The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Math::BSpline::Curve - B-spline curves

VERSION

version 0.002

SYNOPSIS

    use Math::BSpline::Curve;

    my $c = Math::BSpline::Curve->new(
        degree         => 3,
        knot_vector    => [0, 0, 0, 0, 1, 1, 1, 1],
        control_points => [
            [1,  2],
            [2,  3],
            [3,  0],
            [2, -1],
        ],
    );

    my $p = $curve->evaluate(0.3);
    my $d = $curve->evaluate_derivatives(0.3, 3);

    my $dc = $curve->derivative;
    my $v  = $dc->evaluate(0.3);

DESCRIPTION

A B-spline curve of degree p is a curve built upon B-spline basis functions of degree p and a set of control points. The well-known Bezier curves are a special case of B-spline curves. For more information on B-spline basis functions see Math::BSpline::Basis.

CONSTRUCTORS

new

    $curve = Math::BSpline::Curve->new(
        degree         => 3,
        knot_vector    => [0, 0, 0, 0, 1, 1, 1, 1],
        control_points => [
            [1,  2],
            [2,  3],
            [3,  0],
            [2, -1],
        ],
    );

Parameters:

degree (mandatory)

The degree of the B-splines.

knot_vector

The knot vector as array reference. This module only supports clamped knot vectors. It must be a sequence of non-decreasing numbers with p+1 copies of the same number at the beginning and p+1 copies of the same number at the end. In order to achieve a valid knot vector, some automatic trimming is applied by Math::BSpline::Basis on a copy of the knot vector while the original value remains unchanged. In particular, the knot vector is clamped, sorted, and the multiplicity of internal breakpoints is limited to p. However, no fool-proof validation is performed, specifically, the knot vector is not validated against undefined or non-numeric values. For a full discussion of knot vector munging see Math::BSpline::Basis.

If not specified at all, the knot vector defaults to [0,...,0, 1,...,1] with p+1 copies each. This results in a Bezier curve of degree p.

control_points

The list of control points as array reference. If the knot vector contains numbers u_0,...,u_m then you should provide control points P_0,...,P_n with n = m - p - 1. This is currently not enforced, but it might be in a future release.

A control point can either be an array reference to the coordinates of the control points or an object that overloads addition (+) and scalar multiplication (*). Most vector and matrix classes do this. Whatever you choose, all control points should be of the same type.

fit

    $curve = Math::BSpline::Curve->fit(
        degree => 3,
        points => [
            [0.000, 0.000],
            [0.789, 0.503],
            [1.579, -0.012],
            [2.368, -1.534],
            [3.158, -2.857],
            [3.947, -2.474],
            [4.737, 0.105],
            [5.526, 3.635],
            [6.316, 5.712],
            [7.105, 4.376],
            [7.895, -0.291],
            [8.684, -5.800],
        ],
        n_control_points => 6,
    );

See APPROXIMATION below.

ATTRIBUTES

degree

The degree of the spline curve. Must be set at construction and cannot be modified afterwards.

knot_vector

An array reference to the knot vector of the B-splines. Can only be set at construction. Defaults to [0,...,0, 1,...,1] resulting in a Bezier curve.

control_points

An array reference to the control points for the B-spline curve. Can only be set at construction.

basis

The corresponding Math::BSpline::Basis object used to evaluate the curve. You typically do not need to care about this.

METHODS

evaluate

  $p = $curve->evaluate($u)

Evaluates the spline curve at the given position. The returned object or array reference is of the same type as the control points.

evaluate_derivatives

  $d = $curve->evaluate_derivatives($u, $k)

Returns an array reference containing the point and all derivatives up to and including $k at $u. The returned objects or array references are of the same type as the control points.

derivative

  $curve->derivative

The derivative of a B-spline curve of degree p is a B-spline curve of degree p-1. This method returns a Math::BSpline::Curve object representing this derivative.

CAVEAT: Math::BSpline::Basis and therefore also Math::BSpline::Curve only support B-splines that are internally continuous. If your curve is of degree p and if it has an internal knot u_i of multiplicity p then the derivative is discontinuous at u_i. In this case, the derivative method will not fail, but return a continuous B-spline curve, which is not the correct derivative. This behavior might change in a future release.

APPROXIMATION

WARNING: This feature is pre-alpha. I have done some plausibility testing and the results make sense, but to verify that they are really correct is not so simple.

The fit constructor accepts a list of points and fits a B-spline with the given number of control points to it such that the sum of squared distances is minimized for each component.

Background remark: Thism eans that e.g. in 3 dimensions the x, y, and z components of the control points are fitted separately thereby minimizing the squared distance of the x components of the given point to the B-spline curve in x and the same for y and z. The result is not necessarily the same as minimizing the sum of the squared Euclidean distances in space of the points from the curve.

LOGGING

This distribution uses Log::Any for logging. Some methods just return undef on error and log the error. If you just want to print the messages include

    use Log::Any::Adapter ('Sterr');

in your application. See Log::Any for more options.

ACKNOWLEDGEMENTS

This implementation is based on the theory and algorithms presented in the NURBS book.

[1] Piegl, L., Tiller, W.: The NURBS book, 2nd Edition. Springer, 1997.

AUTHOR

Lutz Gehlen <perl@lutzgehlen.de>

COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Lutz Gehlen.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.