# H3DU.BSplineCurve

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

**Augments:** H3DU.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.

**Bézier Curves**

A Bézier curve is defined by a series of control points, where the first and last control points define the end points of the curve, 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 H3DU.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 H3DU.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 control points to homogeneous coordinates, multiply each
conventional coordinate 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 NxN.

Each "column" of a basis matrix is a polynomial equation
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
3xt^{3} + 4xt^{2} + 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 H3DU.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

`controlPoints`

(Type: Array.<Array.<number>>)

An array of control points. Each control point is an array with the same length as the other control points. It is assumed that the first control point's length represents the size of all the control points.`knots`

(Type: Array.<number>)

Knot vector of the curve. Its size must be at least 2 plus the number of control points and not more than twice the number of control points.

The length of this parameter minus 1, minus the number of control points, represents the*degree*of the B-spline curve. For example, a degree-3 (cubic) B-spline curve contains eight knots, that is, four more knots than the number of control points (four). A degree of 1 results in straight line segments.

The knot vector must be a monotonically nondecreasing sequence, the first knot must not equal the last, and the same knot may not be repeated more than N+1 times at the beginning and end of the vector, or more than N times elsewhere, where N is the curve's degree. If the difference between one knot and the next isn't the same, the curve is considered a*non-uniform*B-spline curve. Usually the first knot will be 0 or less and the last knot will be 1 or greater.`bits`

(Type: number) (optional)

Bits for defining input and controlling output. Zero or more of H3DU.BSplineCurve.WEIGHTED_BIT, H3DU.BSplineCurve.HOMOGENEOUS_BIT, and H3DU.BSplineCurve.DIVIDE_BIT. If null, undefined, or omitted, no bits are set.

#### Example

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 Bezier 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=H3DU.Math.mat4invert(destBasis)
// Step 2: Multiply the inverted destination matrix by the source
// matrix
var resultMatrix=H3DU.Math.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=H3DU.Math.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 Bezier 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 Bezier knot vector
);
// Alternatively, the curve could be generated with the
// fromBezierCurve method:
// var curve=BSplineCurve.fromBezierCurve(newControlPoints);
```

### Members

- DIVIDE_BIT

Indicates to divide each other coordinate of the returned point by the last coordinate of the point and omit the last coordinate. - HOMOGENEOUS_BIT
**Deprecated: This bit is deprecated because the B-spline equation works the same whether control points are in conventional coordinates or in homogeneous coordinates.** - WEIGHTED_BIT
**Deprecated: Support for this control point format may be dropped in the future. Instead of using this bit, supply control points in homogeneous coordinates (where each other coordinate is premultiplied by the last) and use**`DIVIDE_BIT`

to convert the results to conventional coordinates. - WEIGHTED_DIVIDE_BITS
**Deprecated: Deprecated because WEIGHTED_BIT is deprecated.**

### Methods

- accel

Finds an approximate acceleration vector at the given U coordinate of this curve. - arcLength

Finds an approximate arc length (distance) between the start of this curve and the point at the given U coordinate of this curve. - changeEnds

Creates a curve evaluator object for a curve that is generated using the same formula as this one (and uses the same U coordinates), but has a different set of end points. - clamped

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

Generates a knot vector with uniform knots, to be passed to the H3DU.BSplineCurve or H3DU.BSplineCurve constructor, except that with the knot vector 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. - endPoints

Returns the starting and coordinates of this curve. - evaluate

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

Creates a curve evaluator object for a curve that follows the same path as this one but has its U coordinates remapped to fit the given range. - fromBezierCurve

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

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

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

Convenience method for getting the total length of this curve. - getPoints

Gets an array of positions on the curve at fixed intervals of U coordinates. - jerk

Finds an approximate jerk vector at the given U coordinate of this curve. - normal

Finds an approximate principal normal vector at the given U coordinate of this curve. - split

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

Convenience method for finding an approximate tangent vector of this curve at the given U coordinate. - toArcLengthParam

Creates a curve evaluator object for a curve that follows the same path as this one but has its U coordinates remapped to an*arc length parameterization*. - uniform

Creates a B-spline curve with uniform knots. - uniformKnots

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

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

### 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`

### H3DU.BSplineCurve.HOMOGENEOUS_BIT (constant)

**Deprecated: This bit is deprecated because the B-spline
equation works the same whether control points are in conventional
coordinates or in homogeneous coordinates.**

Indicates that each other coordinate of each control point was premultiplied by the last coordinate of the point, that is, each control point is in homogeneous coordinates. Only used with WEIGHTED_BIT.

Default Value: `4`

### H3DU.BSplineCurve.WEIGHTED_BIT (constant)

**Deprecated: Support for this control point format may be dropped
in the future. Instead of using this bit, supply control points in homogeneous
coordinates (where each other coordinate is premultiplied by the last)
and use DIVIDE_BIT to convert the
results to conventional coordinates.**

Indicates whether the last coordinate of each control point is a
weight. If some of the weights differ, the curve is
considered a *rational* B-spline curve.
If this bit is set, points returned by the curve's `evaluate`

method will be in homogeneous coordinates.

Default Value: `1`

### H3DU.BSplineCurve.WEIGHTED_DIVIDE_BITS (constant)

**Deprecated: Deprecated because WEIGHTED_BIT is deprecated.**

Combination of WEIGHTED_BIT and DIVIDE_BIT.

### H3DU.BSplineCurve#accel(u)

Finds an approximate acceleration vector at the given U coordinate of this curve.
The implementation in H3DU.Curve calls the evaluator's `accel`

method if it implements it; otherwise, does a numerical differentiation using
the velocity vector.

The **acceleration** of a curve is a vector which is the second-order derivative of the curve's position at the given coordinate. The vector returned by this method *should not* be "normalized" to a unit vector.

#### Parameters

`u`

(Type: number)

U coordinate of a point on the curve.

#### Return Value

An array describing an acceleration vector. It should have at least as many elements as the number of dimensions of the underlying curve. (Type: Array.<number>)

### H3DU.BSplineCurve#arcLength(u)

Finds an approximate arc length (distance) between the start of this
curve and the point at the given U coordinate of this curve.
The implementation in H3DU.Curve calls the evaluator's `arcLength`

method if it implements it; otherwise, calculates a numerical integral using the velocity vector.

The **arc length** function returns a number; if the curve is "smooth", this is the integral, from the starting point to `u`

, of the length of the velocity vector.

#### Parameters

`u`

(Type: number)

U coordinate of a point on the curve.

#### Return Value

The approximate arc length of this curve at the given U coordinate. (Type: number)

### H3DU.BSplineCurve#changeEnds(ep1, ep2)

Creates a curve evaluator object for a curve that is generated using the same formula as this one (and uses the same U coordinates), but has a different set of end points. For example, this method can be used to shrink the path of a curve from [0, π] to [0, π/8].

Note, however, that in general, shrinking the range of a curve will not shrink the length of a curve in the same proportion, unless the curve's path runs at constant speed with respect to time. For example, shrinking the range of a curve from [0, 1] to [0, 0.5] will not generally result in a curve that's exactly half as long as the original curve.

#### Parameters

`ep1`

(Type: number)

New start point of the curve.`ep2`

(Type: number)

New end point of the curve.

#### Return Value

Return value. (Type: H3DU.Curve)

### (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

`controlPoints`

(Type: Array.<Array.<number>>)

Array of control points as specified in the H3DU.BSplineCurve constructor.`degree`

(Type: number) (optional)

Degree of the B-spline curve. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.`bits`

(Type: number) (optional)

Bits as specified in the H3DU.BSplineCurve constructor.

#### 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: H3DU.BSplineCurve)

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

Generates a knot vector with uniform knots, to be passed to the H3DU.BSplineCurve or H3DU.BSplineCurve constructor, except that with the knot vector 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

`controlPoints`

(Type: number | Object)

Number of control points the curve will have, or an array of control points.`degree`

(Type: number) (optional)

Degree of the B-spline curve. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.

#### Return Value

A clamped uniform knot vector. The first knot will be 0 and the last knot will be 1. (This is a change in version 2.0.) (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

`u`

(Type: number)

Point on the curve to evaluate. NOTE: Since version 2.0, this parameter is no longer scaled according to the curve's knot vector. To get the curve's extents, call this object's`endPoints`

method.

#### 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>)

#### Example

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

### H3DU.BSplineCurve#fitRange(ep1, ep2)

Creates a curve evaluator object for a curve that follows the same path as this one but has its U coordinates remapped to fit the given range. For example, this method can be used to shrink the range of U coordinates from [-π, π] to [0, 1] without shortening the path of the curve. Here, -π now maps to 0, and π now maps to 1.

#### Parameters

`ep1`

(Type: number)

New value to use as the start point of the curve.`ep2`

(Type: number)

New value to use as the end point of the curve.

#### Return Value

Return value. (Type: H3DU.Curve)

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

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

#### Parameters

`controlPoints`

(Type: Array.<Array.<number>>)

An array of control points. Each control point is an array with the same length as the other control points. It is assumed that:- The length of this parameter minus 1 represents the degree of the Bézier curve. For example, a degree-3 (cubic) curve contains 4 control points. A degree of 1 (two control points) results in a straight line segment.
- The first control point's length represents the size of all the control points.

`bits`

(Type: number) (optional)

Bits as specified in the H3DU.BSplineCurve constructor.

#### Return Value

Return value. (Type: H3DU.BSplineCurve)

#### Example

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(H3DU.BSplineCurve.fromBezierCurve([cp,np]))
}
return new H3DU.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 H3DU.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 H3DU.BSplineCurve. (Type: Array.<Array.<number>>)

### H3DU.BSplineCurve#getLength()

Convenience method for getting the total length of this curve.

#### Return Value

The distance from the start of the curve to its end. (Type: number)

### H3DU.BSplineCurve#getPoints(count)

Gets an array of positions on the curve at fixed intervals of U coordinates. Note that these positions will not generally be evenly spaced along the curve unless the curve uses an arc-length parameterization.

#### Parameters

`count`

(Type: number)

Number of positions to generate. Throws an error if this number is 0. If this value is 1, returns an array containing the starting point of this curve.

#### Return Value

An array of curve positions. The first element will be the start of the curve. If "count" is 2 or greater, the last element will be the end of the curve. (Type: Array.<Array.<number>>)

### H3DU.BSplineCurve#jerk(u)

Finds an approximate jerk vector at the given U coordinate of this curve.
The implementation in H3DU.Curve calls the evaluator's `jerk`

method if it implements it; otherwise, does a numerical differentiation using
the acceleration vector.

The **jerk** of a curve is a vector which is the third-order derivative of the curve's position at the given coordinate. The vector returned by this method *should not* be "normalized" to a unit vector.

#### Parameters

`u`

(Type: number)

U coordinate of a point on the curve.

#### Return Value

An array describing a jerk vector. It should have at least as many elements as the number of dimensions of the underlying curve. (Type: Array.<number>)

### H3DU.BSplineCurve#normal(u)

Finds an approximate principal normal vector at the given U coordinate of this curve.
The implementation in H3DU.Curve calls the evaluator's `normal`

method if it implements it; otherwise, does a numerical differentiation using the velocity vector.

The **principal normal** of a curve is the derivative of the "normalized" velocity
vector divided by that derivative's length. The normal returned by this method
*should* be "normalized" to a unit vector. (Compare with H3DU.Surface#gradient.)

#### Parameters

`u`

(Type: number)

U coordinate of a point on the curve.

#### Return Value

An array describing a normal vector. It should have at least as many elements as the number of dimensions of the underlying curve. (Type: Array.<number>)

### H3DU.BSplineCurve#split(u)

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

#### Parameters

`u`

(Type: number)

Point on the curve where this curve will be split.

#### 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.<H3DU.BSplineCurve>)

### H3DU.BSplineCurve#tangent(u)

Convenience method for finding an approximate tangent vector of this curve at the given U coordinate.
The **tangent vector** is the same as the velocity vector, but "normalized" to a unit vector.

#### Parameters

`u`

(Type: number)

U coordinate of a point on the curve.

#### Return Value

An array describing a normal vector. It should have at least as many elements as the number of dimensions of the underlying curve. (Type: Array.<number>)

### H3DU.BSplineCurve#toArcLengthParam()

Creates a curve evaluator object for a curve that follows the same
path as this one but has its U coordinates remapped to
an *arc length parameterization*. Arc length
parameterization allows for moving along a curve's path at a uniform
speed and for generating points which are spaced evenly along that
path -- both features are more difficult with most other kinds
of curve parameterization.

The *end points* of the curve (obtained by calling the `endPoints`

method) will be (0, N), where N is the distance to the end of the curve from its
start.

When converting to an arc length parameterization, the curve should be continuous and have a speed greater than 0 at every point on the curve. The arc length parameterization used in this method is approximate.

#### Return Value

Return value. (Type: H3DU.Curve)

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

Creates a B-spline curve with uniform knots.

#### Parameters

`controlPoints`

(Type: Array.<Array.<number>>)

Array of control points as specified in the H3DU.BSplineCurve constructor.`degree`

(Type: number) (optional)

Degree of the B-spline curve. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.`bits`

(Type: number) (optional)

Bits as specified in the H3DU.BSplineCurve constructor.

#### 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: H3DU.BSplineCurve)

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

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

#### Parameters

`controlPoints`

(Type: number | Object)

Number of control points the curve will have, or an array of control points.`degree`

(Type: number) (optional)

Degree of the B-spline curve. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.

#### 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

`u`

(Type: number)

Point on the curve to evaluate.

#### 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>)