Computer Graphics · Geometry Representation

NURBS Knot Vectors and What Rational Weights Do

How a knot vector fixes the basis, why homogeneous coordinates let one polynomial form describe exact circles, and what non-uniform spacing costs downstream.

A B-spline curve of degree $p$ is a weighted sum of $p+1$ control points, but the weights are not constants: they are piecewise polynomials whose shape is determined entirely by a sequence of numbers called the knot vector. Change the knots and the same control polygon produces a different curve, with different continuity, different parameterization, and a different number of basis functions. The knot vector is the part of a spline that beginners skip and that determines almost everything.

What the knot vector encodes

The knot vector $U = {u_0, u_1, \dots, u_m}$ is a non-decreasing sequence of real numbers. For $n+1$ control points and degree $p$, $m = n + p + 1$. The vector divides the parameter range into spans, and on each span a different polynomial applies. Between knots the curve is a polynomial of degree $p$; at a knot of multiplicity $k$ the continuity drops to $C^{p-k}$.

A clamped knot vector repeats its end values $p+1$ times. For a cubic with four control points that gives $U = {0,0,0,0,1,1,1,1}$ and yields a single Bézier segment. Adding interior knots splits the parameter range and increases the control point count by one per knot, without changing the shape of the curve if the new control points are computed by the knot insertion algorithm. This is the property that makes splines useful for design: refinement is exactly shape-preserving, because knot insertion is a change of basis in the same vector space.

A fully uniform vector, with equal spacing everywhere including at the ends, produces basis functions that are shifted copies of each other. Such a curve does not interpolate its end control points; it starts somewhere inside the control polygon. That behaviour is rarely wanted, which is why clamped vectors dominate in practice.

The basis functions themselves are defined by the Cox–de Boor recursion: degree zero is the indicator of each knot span, and degree $p$ is a blend of two degree $p-1$ functions with weights given by the knot ratios. The recursion is the practical evaluation method, and the de Boor algorithm is its numerically stable, $O(p^2)$-per-point reformulation. Since $p$ is usually 3 to 7, the cost per evaluated point is small and independent of the control point count, because only $p+1$ control points influence any parameter value. That local support is the reason a spline with thousands of control points still evaluates in constant time.

Why polynomial basis functions cannot draw a circle

An exact circle of radius $r$ centred at the origin has the parametric form $x = r(1-t^2)/(1+t^2)$, $y = 2rt/(1+t^2)$. The denominators are the problem. A polynomial in $t$ cannot equal a rational function of $t$ on an interval unless the rational function is itself polynomial, and a circle’s coordinate functions are not. So no polynomial B-spline of any degree represents a circle exactly, no matter how many control points are used.

The standard remedy is to work in one dimension higher. Attach a weight $w_i$ to each control point, promote it to a homogeneous coordinate $(w_i x_i, w_i y_i, w_i z_i, w_i)$, and evaluate a plain B-spline in four dimensions. Projecting back by dividing the first three components by the fourth gives a rational curve:

$$ C(u) = \frac{\sum_{i=0}^{n} N_{i,p}(u), w_i, P_i}{\sum_{i=0}^{n} N_{i,p}(u), w_i}. $$

With all weights equal the denominator is constant and the form collapses to the polynomial case, so rational splines are a strict generalization. The projection is the same map used in projective geometry, and the reason it produces circles is that a circle is a conic section: it is the projection of a parabola on a plane in one higher dimension. A quadratic rational B-spline with three control points and suitable weights reproduces a circular arc exactly, which is why the common rational arc uses degree 2 rather than degree 3.

def nurbs_point(degree, knots, ctrl, weights, u):
    """De Boor in homogeneous coordinates; ctrl is [(x, y, z)], weights a list."""
    n = len(ctrl) - 1
    u = min(max(u, knots[degree]), knots[n + 1])   # clamp to the valid domain
    k = degree
    for i in range(degree, n + 1):
        if knots[i] <= u:
            k = i                                  # span index, in [degree, n]
    d = [[weights[j] * c for c in ctrl[j]] + [weights[j]]
         for j in range(k - degree, k + 1)]
    for r in range(1, degree + 1):
        for j in range(degree, r - 1, -1):
            i = j + k - degree
            alpha = (u - knots[i]) / (knots[i + degree + 1 - r] - knots[i])
            d[j] = [(1 - alpha) * d[j - 1][m] + alpha * d[j][m] for m in range(4)]
    w = d[degree][3]
    return tuple(c / w for c in d[degree][:3])

For a quarter circle, degree 2, knots [0, 0, 0, 1, 1, 1], control points $(1,0)$, $(1,1)$, $(0,1)$ and weights $1, \sqrt{2}/2, 1$, every evaluated point lies at distance exactly 1 from the origin. Setting all weights to 1 collapses the same routine to the polynomial B-spline case.

The consequence of a rational representation

Weights give the designer a knob that no amount of control point manipulation can replicate. Increasing one weight pulls the curve toward that control point without adding a knot; decreasing it pushes away. For a circular arc built from three control points and a quadratic basis, the middle weight is $\cos(\theta/2)$ where $\theta$ is the sweep angle, so a quarter circle needs $\cos(\pi/4) = \sqrt{2}/2 \approx 0.7071$ and a full circle is four such arcs joined. The formula also shows the limit: as $\theta$ approaches $\pi$ the weight approaches zero and the arc degenerates, which is why a single quadratic segment represents less than a half circle and why larger arcs are chained.

The cost is that every geometric predicate must now account for the projection. Derivatives of a rational curve are not obtained by differentiating the numerator alone; the quotient rule introduces a term involving the derivative of the denominator, and second derivatives carry more terms still. Curvature, torsion, and offset computations therefore cost more on rational splines than on polynomial ones, and they require the denominator to stay away from zero. Since the denominator is the sum of basis functions times weights, non-negative weights make it strictly positive on the parameter domain, and every sound implementation enforces that.

Non-uniform knots and the problems they cause

Uniform knots make basis functions translates and give the curve a parameterization proportional to its control point spacing. Non-uniform knots let a designer place more detail in one region, but they decouple the parameter from arc length in a way that is hard to predict. A curve with a very short knot span can have enormous derivatives in that span, and the relationship between a parameter step and a geometric distance is no longer approximately constant.

This has three concrete consequences. First, tessellation by uniform parameter steps produces wildly uneven triangle sizes, so adaptive tessellation must measure geometric error rather than parameter error. Second, knot vectors with repeated interior knots reduce continuity, and a curve with an interior knot of multiplicity $p$ has a $C^0$ point there — a visible crease in a surface that is nominally smooth. Third, the numerical conditioning of de Boor’s algorithm degrades when knot spans differ by many orders of magnitude, because the alpha ratios become extreme.

For surfaces the same structure appears twice, as two knot vectors $U$ and $V$, and the surface is a tensor product of the two bases. The control net is a rectangular grid of $(n+1) \times (m+1)$ points in the non-rational case. This rectangular requirement is the crucial limitation: a NURBS surface is a deformed rectangle, and a shape with a hole or a branching topology cannot be one patch. Trimming curves cut the parameter domain, but they do not change the underlying rectangle, so a trimmed surface’s true boundary is not representable as a NURBS curve in the same patch.

That mismatch is why CAD models built from NURBS patches and meshes built from Catmull-Clark subdivision occupy different niches. Subdivision handles arbitrary connectivity with an approximate surface; NURBS handles exact conics with a rectangular parameter domain. Converting between them loses one of the two guarantees, and the loss is not recoverable by increasing resolution.

Trimming, and where the exactness claim ends

Trimming is the practical answer to the topology problem and it introduces a class of defects that consumes a disproportionate share of interoperability effort. A trimmed patch carries a rectangle of control points plus a set of curves in parameter space that mark which parts are real. The trimming curves may be NURBS themselves or arbitrary polylines, and the region they bound is evaluated by point-in-polygon tests in parameter space.

The result is that the surface’s topology lives outside the surface’s own definition. Two adjacent trimmed patches meet along a shared edge only if their trimming curves coincide, and in an exchanged model they frequently do not, because the trimming curves were approximated or the tolerance differs between the exporting and importing systems. The gaps are small relative to model size and absolutely fatal to a solid-modelling kernel that needs a watertight boundary. It is the same class of failure as a mesh with inconsistent face orientation, in a representation where the fix is harder because the boundary is not where the data says it is.

References

  1. The NURBS Book, second edition — Piegl & Tiller, Springer
  2. An Introduction to NURBS: With Historical Perspective — David F. Rogers, Morgan Kaufmann
  3. The Open CASCADE Technology documentation — Open CASCADE