Bezier patch trouble

Don’t we all love the argument list on gluNurbsSurface() ? Well, it’s struck again, and I’m stuck. I want to make a Bezier surface out of an array of 100*100 control points. This means I need 100 knots, right? so what’s wrong about the following:

int ctrlPoint[100][100][3];
float knots[104];

for(int i=0; i<104; ++i){

…//yes, I do call gluBeginSurface()
104, knots,
104, knots,
3, //stride in one direction
300, //stride in other direction
4, 4, //orders

I am not sure about the order of the arguments at the moment, but it looks like that. Could somebody also explain to me what the knots are? My math shouldn’t be the problem.

A bezier patch is formed from 16 Control Points - 4x4. Forming surfaces from any more than that, will mean that you have to start joining patches together. This leads to its own problems because you have to maintain tangent continuity between patches so that you dont see the joins between them.

NURBS surfaces are somewhat different in their approach as they allow any number of control points. To explain what knots are is fairly difficult, so bear with me if this makes no sense - took me ages to get it.

A NURBS curve is a polynomial equation where the highest power is referred to as the degree of the curve, and the order is degree+1. to help explain a bit more :

the cubic bezier curve equation is given as :

Q(t) = (1-t)^3P0 + (1-t)^2tP1 + (1-t)t^2P2 + t^3P3

Where P0->P4 are the four control points

here the degree is 3 (the highest power is three) and the order is 4. If we were to represent this with a NURBS curve, it would require 8 knots, which would look like :


using a parametric curve we have the variable t that varies between 0 and 1. now, unlike a cubic bezier curve, splines do not touch any of their control points. If we were to presume that a single spline segment made up that curve, we would find a very small segment being drawn between the control points P1 & P2.

We need therefore to create a blag. We draw the curve using 5 curve segments in order to clamp it to P0 & P3. The curves are drawn using 4 control points as follows :

Curve1 : P0 P0 P0 P1
Curve2 : P0 P0 P1 P2
Curve3 : P0 P1 P2 P3
Curve4 : P1 P2 P3 P3
Curve5 : P2 P3 P3 P3

Looking at that, we can pretend to use 8 control points to create our curve :

P0 P0 P0 P1 P2 P3 P3 P3

Each curve segment will use four points, but the first control point used will move on one each time. This is a bit of a pain, to draw this curve we would need to store eight control points, of which a lot would be duplicated. Not very clean or efficient.

There is a twist here though, someone came along and invented the Cox-d’Boor algorithm. It is a recursive formula that for given values of t and a given control point, will calculate the effect of that control point at that point of the curve.

NOTE : The way this works is ‘simple’ once you get your head round it, its just very different. for any given t value, we run through EVERY control point, find out the effect that it has on the curve at that point, multiply this value with the control point and sum it. The end sum is the point on the curve.

Go back, read that last paragraph until you understand.

The knot values are used internally within the Cox-De-Boor algorithm to calculate these blending values. Realistically, you dont need to worry about them once you’ve passed them into the Cox-De-Boor. To help explain your problem :

you have a surface of 100x100 points. You’ve specified that your order is 4, ie, the highest power is 3. Now that imples that each curve segment will require 4 control points in order to draw it. So, yes you need 104 knots, however your knots dont match this declaration.

your knot vector should look like

0,0,0,1,2,3,4, … 98,99,100,100,100

The other possibility is that your knots are correct, but you order declaration is wrong. For you knots to work you’d need 5 curve segments in each direction, this would imply that the degree is 99, and the order is 100. I can assure you that you do not want an order that high. It will take years to render.

One more point, using gluNurbs is very very slow… It is actually much better to write your own code in order to sort out NURBS stuff because it gives you a very good understanding of the maths, and there are a lot of optimisations you can take to speed them up considerably.

If you need some source or have any other questions, just mail me.