How to draw a bezier curve through its control points

Hi there,

Really stupid misunderstanding on my part coming up, I'm sure, but I was wondering how to draw a curve through its control points. I'm really quite a newbie when it comes to beziers and NURBs etc., but my requirement is simple and I'm sure that it has been done many, many times - I just haven't found a good enough resource for silly old me on the net.

Here's my code using a Bezier curve - I'm actually wondering if NURBs will get me there. Perhaps someone can modify the code below to make the curve pass through the control points...

Re: How to draw a bezier curve through its control points

Hi Huntc,

A Bezier curve will only interpolate its first and last control points, but will be constrained to the convex hull of all control points. Likewise, a NURBS curve can be made to interpolate control points by replicating knot vector values for particular control point (if first and last are replicated and all weights = 1, it reduces to a Bezier curve).

You may want to look at Catmull-Rom splines, if you need to interpolate all points rather than fit an approximating curve through them. While not offered by OpenGL, Catmull-Rom splines are not at all difficult to implement. Note that this class of curve does not have the convex hull property, and certain classes of shapes, like circles, can't be modelled with this curve (but can be with NURBS).

There are many other curve types, but I hope that this helps to get you started.

Re: How to draw a bezier curve through its control points

Hi guys,

That's a great website. I gave it a quick scan and saw a bunch of good info on curves.

I went ahead and threw together a quick sample demonstrating the basics of Catmull-Rom. The first function uniformly subdivides the control points into time intervals, while the second function simply evaluates the polynomial. The gist of it is to calculate the curve points only when the control points change, so as to avoid unnecessary calculations.

The code is C#, so I hope it is recognizable. I haven't had much time to test this today, but I hope that it helps.

#include <boost/shared_array.hpp>
class CatmullRomSpline
{
public:
// ctor/dtor
CatmullRomSpline(unsigned long inStride, unsigned long inOrder, float* inPointsP) throw();
// An array of a vertex expressed as x, y, z control points. The points array
// will be copied by this object. Thus the caller is responsible
// for any deallocation of the points array passed in.
// Stride specifies the number of floats between the beginning
// of one control point and the beginning of the next one in the
// data structure referenced in inPointsP.
// Order is the number of control points.
// Accessors
void Eval(float f, float* outVertexP) const throw();
// For a given percentage, f (0.0 -> 1.0) return the vertex
protected:
// ctor/dtor
CatmullRomSpline() throw();
private:
// Miscellaneous state
struct Vertex
{
float x;
float y;
float z;
};
const unsigned long mOrder;
boost::shared_array<Vertex> mPointsP;
};

...and finally here's my implementation based on the work of Bill and others: