Rhino's Gallery. lots of cool images made with their NURBS modeller.
Breezy Intro for GEEKS #1 scanned from a world famous PEX book (Hardenbergh)
Breezy Intro for GEEKS #2 CAUTION, some formulas...
The source for the application is twist1.py and it is a terrible mess of a UI, but, it has been useful to me. Perhaps you will find it useful. You will also need Point.py
def C(t, order, points, weights, knots): c = Point([0,0,0]) rational = 0 i = 0 while i < len(points): b = B(i, order, t, knots) p = points[i] * (b * weights[i]) c = c + p rational = rational + b*weights[i] i = i + 1 return c * (1.0/rational) def B(i,k,t,knots): ret = 0 if k>0: n1 = (t-knots[i])*B(i,k-1,t,knots) d1 = knots[i+k] - knots[i] n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots) d2 = knots[i+k+1] - knots[i+1] if d1 > 0.0001 or d1 < -0.0001: a = n1 / d1 else: a = 0 if d2 > 0.0001 or d2 < -0.0001: b = n2 / d2 else: b = 0 ret = a + b #print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b) else: if knots[i] <= t and t <= knots[i+1]: ret = 1 else: ret = 0 return ret
Circle Example with OpenGL code included below and ancient PEX C code which takes three XYZ points and put a circle thru them. The example is taken from the book Mathematical Elements for Computer Graphics, by David F. Rogers and J Alan Adams.
Here is a little NURBCurve playground using that same example. It evaluates the curve in a very transparent, if very inefficient way. However, if you are trying to build up your understand of how NURBS work, this bit of source if for you.
There is also a good page
based on a talk given to college students by Markus Altmann
/* * OpenGL code for drawing a circle with a NURBS curve. * * Method found on page 374, Mathematical Elements for Computer Graphics, * 2nd ed. David F. Rogers and J Alan Adams. McGraw Hill, 1990. * This is the triangle method, using 7 control points at the corners * and middles of an equilateral triangle, with knot vector * [ 0, 0, 0, 1, 1, 2, 2, 3, 3, 3 ] 10 knots (nCtrlPoints + order) * [ 1.0, 0.5, 1.0, 0.5, 1.0, 0.5, 1.0] weights, one per ctrlPoint. * Control points are the corners and midpoints of an equilateral triangle * 0,0 - 1,0 - 0,sqrt(3)/2 except it has been translated to -.5, -.5 * The first point is repeated as the 7th point. * * see picture at http://www.jch.com/NURBS/NURBCirc.gif * and other notes at http://www.jch.com/NURBS/ * YON - Jan C. Hardenbergh */ GLUnurbsObj *pNurb = NULL; int nCtrlPoints = 7; GLfloat ctrlPoints[7][4]; GLfloat pointsWeights[7][4] = { {0,-.5, 0, 1}, {.5,-.5, 0, 0.5}, {0.25, -0.0669873, 0, 1}, {0, 0.3880254, 0, 0.5}, {-.25, -0.0669873, 0, 1}, {-.5,-.5, 0, 0.5}, {0,-.5, 0, 1}}; // Knot vector int order = 3; int nKnots = 10; GLfloat Knots[10] = {0,0,0,1,1,2,2,3,3,3}; #define kStride 4 // Called to draw scene void RenderScene(void) { int i, j; // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Render the NURB // make sure we are setup if (!pNurb) { // Setup the Nurbs object pNurb = gluNewNurbsRenderer(); gluNurbsProperty(pNurb, GLU_SAMPLING_TOLERANCE, 5.0f); //gluNurbsProperty(pNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); //gluNurbsProperty(pNurb, GLU_DISPLAY_MODE, (GLfloat)GLU_FILL); // make the NURBS control points from the points & weights for(i = 0; i < nCtrlPoints; i++) { ctrlPoints[i][3] = pointsWeights[i][3]; for (j = 0; j < 3; j++) { ctrlPoints[i][j] = pointsWeights[i][j]*ctrlPoints[i][3]; } } } glColor3f(1,0,1); // Begin the NURB definition gluBeginCurve(pNurb); // Send the Non Uniform Rational BSpline gluNurbsCurve(pNurb, nKnots, Knots, kStride, &ctrlPoints[0][0], order, GL_MAP1_VERTEX_4); gluEndCurve(pNurb); // Draw the control points in red glPointSize(3.0f); glColor3f(1,0,0); glBegin(GL_POINTS); for(i = 0; i < nCtrlPoints; i++) glVertex3fv(pointsWeights[i]); glEnd(); // Flush drawing commands glFlush(); }3-DEC-2000 jch - updated 29-MAY-2003