What is a NURBS?

I'll try to explain what a NURBS is, how to evaluate it and what tools allow you to evaluate it. I shortlisted few questions that I hope you'll find useful, if you have others, and I'll add the answer here.

What NURBS stands for?

NURBS is acronym of Non-Uniform Rational B-Splines.

Non-Uniform...what?!

Let's break it down and make it simple to understand. From the end: a spline is a smooth curve. If you draw a smooth curve on a piece of paper, that curve can be seen as a spline. More formally, a spline is a function. Like any other function a spline has an image. Usually, splines have domain from 0 to 1. For the example of the curve drawn on the paper, the beginning corresponds to 0 and the end to 1.

Basis splines (aka B-splines) are just a particular case of splines—the curve you drawn is a B-spline.

The word rational simply means that the function which describes your curve comes from the quotient of two functions. Namely: $$r(x) = \frac{s(x)}{w(x)}.$$

In practice this gives you the ability draw perfect circles. On top of a pencil, now you've got a compass. Without it you could not draw perfect circles. Finally, non-uniform means that if you want to split your curve into two pieces, you don't have to split it uniformly. That's the idea behind NURBS, Wikipedia provides a much more sound explanation about NURBS.

What tools do I need?

Matlab is fun and it has (almost) all you'll need already built-int. Some functions you'll need are open source. If you need something even simple, although limited to curves on a plane, check out this interactive NURBS demo.

NURBS modelling is a well-established technique in computer graphics, robotics and CAD. You can model cartoon characters using NURBS with Blender.

Enough. How do I draw a NURBS curve in Matlab?

x = [0    0.2500    1.5000    1.0000    3.0000    2.2500    3.2500];
y = [0    1.0000    1.3000   -0.7500   -0.7500    0.5000    0.8000];
z = [0         0         0         0         0         0         0];
fnplt( rsmak( aptknt(0:.15:1 , 2+1), [x; y; z] ) 	

That's how your quadratic NURBS looks like:

NURBScurve00

How about NURBS surfaces and solid NURBS?

Once you know what a NURBS curve is it's all downhill. With two curves you can get a surface, with three a solid. The process for doing this is called tensor product and is a lot more intuitive that what it sounds. Grab a piece of paper and hold it from one corner. You can imagine that the two edges closes to your hand are two curves. Just consider two of the four edges. These two edges are indeed curves and the whole paper is your NURBS surface.

% Knot vector
KnotS = [0 0 0 1/3 2/3 1 1 1];
KnotR = [0 0 0 1/3 2/3 1 1 1];
% Control polygon and weights
x = [5  5   5   5   5; 4  4   4   4   4.5; 3  3   3   3   3; 2  2   2   2   2; 1  1   1   1   1];
y = [5  5   5   5   5; 4  4   4   4   4  ; 3  3   3   3   3; 2  2   2   2   2; 1  1.5 0.5 1.5 1]';
z = [1  1   0   0   .5; 1  1   0   0   .5; 2  2   1   1   1.5; 2  2   1   1   1.5; 4  4   3   3   3.3];
w = ones(5,5);
w(2,2) = 10; w(3,2) = 10; w(3,3) = 10;
w = ones(5,5);
w(2,2) = 10; w(3,2) = 10; w(3,3) = 10;
HomCoef = zeros([4,size(x)]);
HomCoef(:,:,1) = [x(1,:).*w(1,:);y(1,:).*w(1,:);z(1,:).*w(1,:);w(1,:)];
HomCoef(:,:,2) = [x(2,:).*w(2,:);y(2,:).*w(2,:);z(2,:).*w(2,:);w(2,:)];
HomCoef(:,:,3) = [x(3,:).*w(3,:);y(3,:).*w(3,:);z(3,:).*w(3,:);w(3,:)];
HomCoef(:,:,4) = [x(4,:).*w(4,:);y(4,:).*w(4,:);z(4,:).*w(4,:);w(4,:)];
HomCoef(:,:,5) = [x(5,:).*w(5,:);y(5,:).*w(5,:);z(5,:).*w(5,:);w(5,:)];
% Build NURBS
rs = rsmak({KnotS,KnotR} , HomCoef);
NURBSsurf00

Slightly more abstract, but the same applies to solid NURBS. You can get a solid NURBS in Matlab by expanding the code above. Unfortunately Matlab does not have any the functionality to visualise solid NURBS, but below is one example

solidnurbs

Further reading

The best reference I can point you to is The NURBS book. It covers in great details curves, surfaces and their properties. It also provides algorithms for evaluating NURBS and their derivatives. Below it's an image, similar one of those in the book, you can do in Matlab. It's fun and is good for learning.

solidnurbs