H3DU.BSplineCurve

Back to documentation index.

new H3DU.BSplineCurve(controlPoints, knots, [bits])

Augments: Curve

A curve evaluator object for a B-spline (basis spline) curve. A B-spline curve is a parametric curve based on polynomial functions. Each polynomial is generated using one or more control points, which more or less follow the path of the curve, and a knot vector, which determines, more or less, where each control point is spaced along the curve. Together with rational B-spline curves (see below), this makes B-spline curves very powerful, since they can describe nearly all curves commonly used in computer graphics, including line segments, circles, ellipses, parabolas, and irregular smooth curves. With the B-spline curves supported here, a perspective transformation (including a rotation, translation, or scaling) of the curve's control points leads to the same transformation of the resulting curve.

Bézier Curves

A Bézier curve is defined by a series of control points, where the first and last control points are the curve's end points, and the remaining control points define the curve's shape, though they don't necessarily cross the curve. An important property of these curves is that the bounding box of the curve is contained within the bounding box of the control points. Another important property is that the starting direction is the same as the direction from the first to the second control point, and the ending direction is the same as the direction from the next-to-last to last control point.

Bézier curves are a subset of B-spline curves (see BSplineCurve.fromBezierCurve).

Line segments are degree-1 Bézier curves with two control points.

A Bézier curve's knot vector consists of as many zeros as the number of control points, followed by that many ones. For example, a degree-3 (cubic) Bézier curve contains four control points and the following knot vector: [0, 0, 0, 0, 1, 1, 1, 1].

Non-Uniform Curves

A non-uniform B-spline curve is one whose knot vector is not evenly spaced, that is, the difference between one knot and the next isn't the same.

Rational Curves

A rational B-spline curve is an N-dimensional curve with N plus one coordinates per control point (homogeneous coordinates). B-spline algorithms work the same way with homogeneous coordinates as with conventional coordinates, but if N-dimensional points are wanted, use the BSplineCurve.DIVIDE_BIT flag to divide each coordinate by the last (and omit the last coordinate) to convert to N-dimensional points.

Rational B-spline curves can describe circles and ellipses, which non-rational B-spline curves can't.

Note that some B-spline packages define rational B-spline curves as using control points and weights, that is, N-dimensional control points in conventional coordinates, along with a separate number, or weight, for each control point. To convert such a control point to homogeneous coordinates, multiply each of its conventional coordinates by its weight, then append the weight as the control point's last coordinate.

NURBS Curves

NURBS is an acronym for non-uniform rational B-spline curves.

Polynomial Basis

Any kind of polynomial curve can be converted to a different kind of polynomial curve, having the same degree and describing the same path, by transforming its control points. For example, a Hermite curve (another kind of polynomial curve) can be converted to the equivalent B-spline curve this way, or vice versa.

Each kind of polynomial curve (such as B-spline or Bézier) is associated with a basis matrix, which defines the polynomial coefficients for each control point in the curve. For a degree (N-1) curve, the matrix will be N×N.

Each "column" of a basis matrix is a polynomial containing the coefficients for each control point, and the columns are arranged from left to right. Each polynomial consists of coefficients, ranging from the highest order to the lowest, with respect to the parameter t and the corresponding control point. For example, the column (3, 4, 2, 10) describes the polynomial 3xt3 + 4xt2 + 2xt + 10x, where x is the input control point. The polynomials are added together to get the final coordinate of the curve at the given t value.

The following JavaScript code shows an example of a basis matrix -- the cubic Bézier basis matrix.

var bezierBasisMatrix = [
// For the purposes of the Math matrix functions,
// the polynomials are arranged "column-wise", like this:
// P1, P2, P3, P4
-1,3,-3,1,
3,-6,3,0,
-3,3,0,0,
1,0,0,0]

For code that converts a curve from one kind to another, see the example.

Parameters

Examples

The following function can be used to convert an array of control points, each consisting of conventional coordinates and a weight, to homogeneous coordinates. For example, the single-control point '[[2, 3, 4, 0.1]]' becomes '[[0.2, 0.3, 0.4, 0.1]]'; the return value can then be used in the BSplineCurve constructor to create a rational B-Spline curve.

function convertToHomogen(cp) {
var ret = [];
var cplen = cp[0].length;
for(var i = 0; i < cp.length; i++) {
var outp = [];
var w = cp[i][cplen - 1];
for(var j = 0; j < cplen - 1; j++) {
outp[j] = cp[i][j] * w;
}
outp[cplen - 1] = w;
ret.push(outp);
}
return ret;
};

The following code converts a cubic (degree-3) curve from one kind to another. The converted curve will generally have the same path as the original curve.

// "srcBasis" is a 4x4 basis matrix for the source curve type;
// the control points will initially be of this type of curve.
// var srcBasis = [ .... ]; // To be supplied or filled in.
// "dstBasis" is a 4x4 basis matrix for the destination curve type.
// It's defined here as the B&eacute;zier basis matrix for this example
var dstBasis =[-1,3,-3,1, 3,-6,3,0, -3,3,0,0, 1,0,0,0];
// Step 1: Invert the destination basis matrix
var invertedDest=MathUtil.mat4invert(destBasis)
// Step 2: Multiply the inverted destination matrix by the source
// matrix
var resultMatrix=MathUtil.mat4multiply(invertedDest,srcBasis)
// Step 3: Convert the control points one dimension
// at a time
var newControlPoints=[[],[],[],[]]
for(var i=0;i < controlPoints[0].length;i++) {
var cp=[controlPoints[0][i],controlPoints[1][i],controlPoints[2][i],
controlPoints[3][i]]
// Transform the control points using the result matrix
cp=MathUtil.vec4transform(resultMatrix,cp)
// Set the new coordinates
newControlPoints[0][i]=cp[0]
newControlPoints[1][i]=cp[1]
newControlPoints[2][i]=cp[2]
newControlPoints[3][i]=cp[3]
}
// Finally, generate a B&eacute;zier curve (which is a special case
// of a B-spline curve)
var curve=new BSplineCurve(
newControlPoints,
[0,0,0,0,1,1,1,1] // cubic B&eacute;zier knot vector
);
// Alternatively, the curve could be generated with the
// fromBezierCurve method:
// var curve=BSplineCurve.fromBezierCurve(newControlPoints);

Members

Methods

H3DU.BSplineCurve.DIVIDE_BIT (constant)

Indicates to divide each other coordinate of the returned point by the last coordinate of the point and omit the last coordinate. This is used to convert homogeneous coordinates to conventional coordinates. If this bit is set, the length of each control point must be at least 2.

A B-spline curve that has control points whose last coordinate is other than 1 is a rational B-spline curve.

Default Value: 2

(static) H3DU.BSplineCurve.clamped(controlPoints, [degree], [bits])

Creates a B-spline curve with uniform knots, except that the curve will start and end at the first and last control points and will be tangent to the line between the first and second control points and to the line between the next-to-last and last control points.

Parameters

Return Value

Return value. The first knot of the curve will be 0 and the last knot will be 1. (Type: BSplineCurve)

(static) H3DU.BSplineCurve.clampedKnots(controlPoints, [degree])

Generates a knot vector with uniform knots, to be passed to the BSplineCurve or BSplineSurface constructor, except that with the knot vector the curve will start and end at the first and last control points and will be tangent to the line between the first and second control points and to the line between the next-to-last and last control points.

Parameters

Return Value

A clamped uniform knot vector. The first knot will be 0 and the last knot will be 1. (Type: Array.<number>)

H3DU.BSplineCurve#endPoints()

Returns the starting and coordinates of this curve.

Return Value

A two-element array containing the starting and ending U coordinates, respectively, of the curve. (Type: Array.<number>)

H3DU.BSplineCurve#evaluate(u)

Evaluates the curve function based on a point in a B-spline curve.

Parameters

Return Value

An array of the result of the evaluation. Its length will be equal to the length of a control point (minus 1 if DIVIDE_BIT is set), as specified in the constructor. (Type: Array.<number>)

Examples

// Generate 11 points forming the curve.
var points=[];
for(var i=0;i<=10;i++) {
points.push(curve.evaluate(i/10.0));
}

(static) H3DU.BSplineCurve.fromBezierCurve(controlPoints, [bits])

Creates a B-spline curve from the control points of a Bézier curve.

Parameters

Return Value

Return value. (Type: BSplineCurve)

Examples

The following function generates a polygon curve using linear Bézier curves.

function polygonCurve(points) {
var curves=[]
for(var i=0;i < points.length;i++) {
var cp=points[i]
var np=(i==points.length-1) ? points[0] : points[i+1]
curves.push(BSplineCurve.fromBezierCurve([cp,np]))
}
return new PiecewiseCurve(curves)
}

H3DU.BSplineCurve#getControlPoints()

Gets a reference to the array of control points used in this curve object.

Return Value

An object described in the constructor to BSplineCurve. (Type: Array.<Array.<number>>)

H3DU.BSplineCurve#getKnots()

Gets a reference to the array of knots used in this curve object.

Return Value

An object described in the constructor to BSplineCurve. (Type: Array.<Array.<number>>)

H3DU.BSplineCurve#split(u)

Splits this B-spline curve into two at the given point.

Parameters

Return Value

An array containing two B-spline curves: the first is the part of the curve before the given point, and the second is the part of the curve after the given point. The first element will be null if u is at or before the start of the curve. The second element will be null if u is at or after the end of the curve. (Type: Array.<BSplineCurve>)

(static) H3DU.BSplineCurve.uniform(controlPoints, [degree], [bits])

Creates a B-spline curve with uniform knots.

Parameters

Return Value

Return value. The first knot of the curve will be 0 and the last knot will be 1. (This is a change from previous versions.) (Type: BSplineCurve)

(static) H3DU.BSplineCurve.uniformKnots(controlPoints, [degree])

Generates a knot vector with uniform knots, to be passed to the BSplineCurve or BSplineSurface constructor.

Parameters

Return Value

A uniform knot vector. The first knot will be 0 and the last knot will be 1. (This is a change from previous versions.) (Type: Array.<number>)

H3DU.BSplineCurve#velocity(u)

Finds the velocity (derivative) of this curve at the given point.

Parameters

Return Value

An array giving the velocity vector. It will have as many elements as a control point (or one fewer if DIVIDE_BIT is set), as specified in the constructor. (Type: Array.<number>)

Back to documentation index.