NURBS in 30 Minutes: The Four Numbers Behind Every Curve You've Ever Lofted
Degree, control points, knots, weight — the mathematics under every Rhino curve, taught hands-on with the open-source rhino3dm library. Clone it and read the four numbers yourself.
Open the Rhino developer docs on NURBS geometry and the whole edifice collapses into one honest sentence: a NURBS curve is defined by four things — degree, control points, knots, and an evaluation rule. That’s it. Everything else you do in Rhino — the free-form roof, the lofted façade, the fillet you swear at — is those four numbers being read by a black box. You do not have to derive the box. But if you cannot name what goes into it, you are operating a curve you cannot defend in a review.
The Signal. The openNURBS overview from McNeel lays out the grammar plainly. Degree is a positive whole number — usually 1, 2, 3 or 5 (linear, quadratic, cubic, quintic). A polyline is degree 1; a NURBS circle is degree 2; most free-form curves are degree 3 or 5. Control points are a list of at least degree+1 points, each carrying a weight. And the knots are a list of exactly degree+N−1 numbers, where N is the count of control points. Four inputs, one rule, infinite shapes.
←TODAY: Rhino 8.34 still evaluates every curve through the same B-spline basis functions De Boor wrote down in 1978. →3012: the file format dies; the four numbers survive, and a 25-year-old rebuilds your façade from the principle, not the .3dm. Fulcrum: a form you can regenerate from degree + points + knots is a form you own — everything else is a beautiful guess.
The System. The B and S in NURBS stand for “basis spline,” and this is where the mathematics actually lives. The evaluation rule blends the control points using B-spline basis functions — little bump functions, each switched on over a window defined by the knot vector. The knots are not paired one-to-one with control points (a common misconception the docs call out explicitly — that pairing is true only for degree-1 polylines). For higher degree, groups of 2×degree knots govern groups of degree+1 control points. Push a control point and only the curve inside its knot window moves; the rest holds. That locality — a decades-old result surveyed by Böhm, Farin and Kahman in the very first volume of Computer Aided Geometric Design (1984) — is the whole reason NURBS editing feels predictable instead of chaotic.
Two visual anchors make the four numbers teachable. Weight is magnet strength: when every control point shares the same weight (usually 1) the curve is non-rational; give one point a heavier weight and the curve is pulled toward it. The R in NURBS is that permission to be rational — and it is why circles and ellipses, which no polynomial can draw exactly, are always rational. Knot multiplicity is the sharpness dial: duplicate a knot value up to degree times and you bend a smooth curve into a kink. The docs’ own worked example — a degree-3 curve with 11 control points and knots 0,0,0,1,2,2,2,3,7,7,9,9,9 — is legal precisely because no value repeats more than three times. Add a fourth 2 and Rhino rejects it.
The Tool: rhino3dm, McNeel’s open-source geometry library — the same openNURBS kernel Rhino ships, exposed as a pip-installable Python module (also JavaScript and .NET). No Rhino licence, no GUI. It is worth a computational designer’s afternoon because it lets you read the four numbers directly — Order, control-point count, weights, knot vector — on any curve, and watch them change as you edit. PAZ has framed Rhinoceros before as NURBS-based modelling in our “Universal glue” piece; rhino3dm is how you get under the hood without the whole application.
Setup:
python -m pip install rhino3dm
# Prove it works: a NURBS circle should report itself as
# degree 2 (order 3), rational, with weighted control points.
python -c "import rhino3dm; c = rhino3dm.NurbsCurve.CreateFromCircle(rhino3dm.Circle(5.0)); print('order', c.Order, '| points', len(c.Points), '| rational', c.IsRational)"
First steps:
- Run the one-liner above. You’ll see
order 3(degree 2), andrational True— exactly what the docs promise for a circle. - Print the knot vector:
print(list(c.Knots)). Count them and check the identity — for a degree-2 rational circle in rhino3dm you’ll see repeated interior knots holding the arc segments together. - Now build a free-form degree-3 curve from four points and print
c.Orderand the knot list. Change the point coordinates, re-run, and watch which knots stay fixed — the vector is structure, not shape. - Bump one control point’s weight (next block) and re-evaluate. The R in NURBS becomes a slider you can feel.
Atelier: For a Swiss studio, the payoff is auditability. When a competition-winning free-form roof comes back for a Bauleitung review, “we generated it in Grasshopper” is not an answer — “it’s a degree-3 curve, uniform knots, all weights 1, so it’s non-rational and reproducible from these fourteen control points” is. The Monday move: add a two-line rhino3dm check to your export routine that prints degree, control-point count and whether the geometry is rational for every curve leaving the office — so no shape ships that you cannot reconstruct from its four numbers alone.
Hack: Pull a single control point’s weight up and watch the curve lean toward it — the geometry of “rational” in four lines.
import rhino3dm
pts = [rhino3dm.Point3d(0,0,0), rhino3dm.Point3d(1,2,0), rhino3dm.Point3d(3,2,0), rhino3dm.Point3d(4,0,0)]
crv = rhino3dm.NurbsCurve.Create(False, 3, pts)
crv.Points.SetWeight(1, 6.0) # magnet #1 gets 6x pull -> now rational
print(crv.PointAt(0.5), crv.IsRational)
Set the weight back to 1.0 and the point at parameter 0.5 shifts back; the curve is non-rational again. You have just operated the R in NURBS by hand.
The Move. The mathematics under Grasshopper — the visual language David Rutten shipped for Rhino in 2007 — is not something you must re-derive every morning. But the four numbers are the difference between a designer and a button-pusher. Clone rhino3dm, read the degree and knots of one curve you built last month, and confirm you can say why it holds. Keep the maths; the file format will not survive you.
Learn-it:
- Repo: github.com/mcneel/rhino3dm — the open openNURBS kernel as a Python/JS/.NET library.
- Primary source: developer.rhino3d.com — NURBS geometry overview, the four-things definition in full.
- Root concept: Non-uniform rational B-spline (Wikipedia) — history from the flat spline held by ducks to IGES/STEP.
- Deeper theory: Carl de Boor, A Practical Guide to Splines (Springer, 1978) — the canonical treatment of the basis functions.
- PAZ note: “Universal glue” — where we framed Rhino’s NURBS core and Grasshopper as the connective tissue of parametric practice.
SOURCE · ↗
PAZ Kaffi · multidisciplinary editorial, led by PAZ Academy