20.3. Examples of NURBS Curves

This section provides two examples of NURBS curves: a B-spline curve and a uniform B-spline curve that passes through the end control points.

Example 20.1, “ Creating a B-Spline Curve creates and displays a B-spline curve. Seven control points are defined. The knot vector contains ten knots. Since

number_of_knots = order + number_of_control_points

this curve has an order of 3. It has a multiplicity of 2 (one knot is used twice). This curve has a continuity of C0.

Figure 20.11, “ Scene Graph for B-Spline Curve Example shows the scene graph for the nodes in this example. Figure 20.12, “ B-Spline Curve shows the resulting curve.



Example 20.1.  Creating a B-Spline Curve

// The control points for this curve
float pts[7][3] = {
   { 4.0, -6.0,  6.0},
   {-4.0,  1.0,  0.0},
   {-1.5,  5.0, -6.0},
   { 0.0,  2.0, -2.0},
   { 1.5,  5.0, -6.0},
   { 4.0,  1.0,  0.0},
   {-4.0, -6.0,  6.0}};

// The knot vector
float knots[10] = {1, 2, 3, 4, 5, 5, 6, 7, 8, 9};

// Create the nodes needed for the B-Spline curve.
SoSeparator *
makeCurve()
{
   SoSeparator *curveSep = new SoSeparator();
   curveSep->ref();

   // Set the draw style of the curve.
   SoDrawStyle *drawStyle  = new SoDrawStyle;
   drawStyle->lineWidth = 4;
   curveSep->addChild(drawStyle);

   // Define the NURBS curve including the control points
   // and a complexity.
   SoComplexity  *complexity = new SoComplexity;
   SoCoordinate3 *controlPts = new SoCoordinate3;
   SoNurbsCurve  *curve      = new SoNurbsCurve;
   complexity->value = 0.8;
   controlPts->point.setValues(0, 7, pts);
   curve->numControlPoints = 7;
   curve->knotVector.setValues(0, 10, knots);
   curveSep->addChild(complexity);
   curveSep->addChild(controlPts);
   curveSep->addChild(curve);

   curveSep->unrefNoDelete();
   return curveSep;
}
    
// The control points for this curve
float[,] pts = new float[7, 3] {
		{ 4.0f, -6.0f,  6.0f},
		{-4.0f,  1.0f,  0.0f},
		{-1.5f,  5.0f, -6.0f},
		{ 0.0f,  2.0f, -2.0f},
		{ 1.5f,  5.0f, -6.0f},
		{ 4.0f,  1.0f,  0.0f},
		{-4.0f, -6.0f,  6.0f}};

// The knot vector
float[] knots = new float[10] { 1, 2, 3, 4, 5, 5, 6, 7, 8, 9 };

// Create the nodes needed for the B-Spline curve.
SoSeparator makeCurve()
{
  SoSeparator curveSep = new SoSeparator();

  // Set the draw style of the curve.
  SoDrawStyle drawStyle = new SoDrawStyle();
  drawStyle.lineWidth.Value = (4);
  curveSep.AddChild(drawStyle);

  // Define the NURBS curve including the control points
  // and a complexity.
  SoComplexity complexity = new SoComplexity();
  SoCoordinate3 controlPts = new SoCoordinate3();
  SoNurbsCurve curve = new SoNurbsCurve();
  complexity.value.Value = (0.8f);
  controlPts.point.SetValues(0, 7, pts);
  curve.numControlPoints.Value = (7);
  curve.knotVector.SetValues(0, knots);
  curveSep.AddChild(complexity);
  curveSep.AddChild(controlPts);
  curveSep.AddChild(curve);

  return curveSep;
}
  
//The control points for this curve
float[][] pts = new float[][] {
        { 4.0f, -6.0f,  6.0f},
        {-4.0f,  1.0f,  0.0f},
        {-1.5f,  5.0f, -6.0f},
        { 0.0f,  2.0f, -2.0f},
        { 1.5f,  5.0f, -6.0f},
        { 4.0f,  1.0f,  0.0f},
        {-4.0f, -6.0f,  6.0f}};

// The knot vector
float[] knots = new float[] { 1, 2, 3, 4, 5, 5, 6, 7, 8, 9 };

// Create the nodes needed for the B-Spline curve.
SoSeparator makeCurve()
{
  SoSeparator curveSep = new SoSeparator();

  // Set the draw style of the curve.
  SoDrawStyle drawStyle = new SoDrawStyle();
  drawStyle.lineWidth.setValue(4);
  curveSep.addChild(drawStyle);

  // Define the NURBS curve including the control points
  // and a complexity.
  SoComplexity complexity = new SoComplexity();
  SoCoordinate3 controlPts = new SoCoordinate3();
  SoNurbsCurve curve = new SoNurbsCurve();
  complexity.value.setValue(0.8f);
  controlPts.point.setValues(0, pts);
  curve.numControlPoints.setValue(7);
  curve.knotVector.setValues(0, knots);
  curveSep.addChild(complexity);
  curveSep.addChild(controlPts);
  curveSep.addChild(curve);

  return curveSep;
}
  

Example 20.2, “ Creating a Uniform B-Spline Curve creates a uniform B-spline curve that passes through the end control points. The knot sequence has a multiplicity of 4 at the beginning and end, which causes the curve to pass through the first and last control points. In between, the curve is uniform.

The scene graph for the nodes in this example has the same structure as the scene graph shown in Figure 20.11, “ Scene Graph for B-Spline Curve Example. Figure 20.13, “ A Uniform B-Spline Curve that Passes through the Endpoints” shows the resulting curve.


Example 20.2.  Creating a Uniform B-Spline Curve

// The control points for this curve
float pts[13][3] = {
   { 6.0,  0.0,  6.0},
   {-5.5,  0.5,  5.5},
   {-5.0,  1.0, -5.0},
   { 4.5,  1.5, -4.5},
   { 4.0,  2.0,  4.0},
   {-3.5,  2.5,  3.5},
   {-3.0,  3.0, -3.0},
   { 2.5,  3.5, -2.5},
   { 2.0,  4.0,  2.0},
   {-1.5,  4.5,  1.5},
   {-1.0,  5.0, -1.0},
   { 0.5,  5.5, -0.5},
   { 0.0,  6.0,  0.0}};

// The knot vector
float knots[17] = {
   0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};

// Create the nodes needed for the B-Spline curve.
SoSeparator *
makeCurve()
{
   SoSeparator *curveSep = new SoSeparator();
   curveSep->ref();

   // Set the draw style of the curve.
   SoDrawStyle *drawStyle  = new SoDrawStyle;
   drawStyle->lineWidth = 4;
   curveSep->addChild(drawStyle);

   // Define the NURBS curve including the control points
   // and a complexity.
   SoComplexity  *complexity = new SoComplexity;
   SoCoordinate3 *controlPts = new SoCoordinate3;
   SoNurbsCurve  *curve      = new SoNurbsCurve;
   complexity->value = 0.8;
   controlPts->point.setValues(0, 13, pts);
   curve->numControlPoints = 13;
   curve->knotVector.setValues(0, 17, knots);
   curveSep->addChild(complexity);
   curveSep->addChild(controlPts);
   curveSep->addChild(curve);

   curveSep->unrefNoDelete();
   return curveSep;
}
                       
// The control points for this curve
float[,] pts = new float[13, 3] 
{
  { 6.0f,  0.0f,  6.0f},
  {-5.5f,  0.5f,  5.5f},
  {-5.0f,  1.0f, -5.0f},
  { 4.5f,  1.5f, -4.5f},
  { 4.0f,  2.0f,  4.0f},
  {-3.5f,  2.5f,  3.5f},
  {-3.0f,  3.0f, -3.0f},
  { 2.5f,  3.5f, -2.5f},
  { 2.0f,  4.0f,  2.0f},
  {-1.5f,  4.5f,  1.5f},
  {-1.0f,  5.0f, -1.0f},
  { 0.5f,  5.5f, -0.5f},
  { 0.0f,  6.0f,  0.0f}
};

// The knot vector
float[] knots = new float[17] 
{
  0, 0, 0, 0,
  1, 2, 3, 4, 
  5, 6, 7, 8, 
  9, 10, 10, 10, 
  10
};

// Create the nodes needed for the B-Spline curve.
SoSeparator
MakeCurve()
{
  SoSeparator curveSep = new SoSeparator();

  // Set the draw style of the curve.
  SoDrawStyle drawStyle = new SoDrawStyle();
  drawStyle.lineWidth.Value = 4;
  curveSep.AddChild(drawStyle);

  // Define the NURBS curve including the control points
  // and a complexity.
  SoComplexity complexity = new SoComplexity();
  SoCoordinate3 controlPts = new SoCoordinate3();
  SoNurbsCurve curve = new SoNurbsCurve();
  complexity.value.Value = 0.8f;
  controlPts.point.SetValues(0, 13, pts);
  curve.numControlPoints.Value = 13;
  curve.knotVector.SetValues(0, knots);
  curveSep.AddChild(complexity);
  curveSep.AddChild(controlPts);
  curveSep.AddChild(curve);

  return curveSep;
}
                     
//The control points for this curve
float[][] pts = new float[][]{
  { 6.0f,  0.0f,  6.0f},
  {-5.5f,  0.5f,  5.5f},
  {-5.0f,  1.0f, -5.0f},
  { 4.5f,  1.5f, -4.5f},
  { 4.0f,  2.0f,  4.0f},
  {-3.5f,  2.5f,  3.5f},
  {-3.0f,  3.0f, -3.0f},
  { 2.5f,  3.5f, -2.5f},
  { 2.0f,  4.0f,  2.0f},
  {-1.5f,  4.5f,  1.5f},
  {-1.0f,  5.0f, -1.0f},
  { 0.5f,  5.5f, -0.5f},
  { 0.0f,  6.0f,  0.0f}
};

// The knot vector
float[] knots = new float[] 
{
  0, 0, 0, 0,
  1, 2, 3, 4, 
  5, 6, 7, 8, 
  9, 10, 10, 10, 
  10
};

// Create the nodes needed for the B-Spline curve.
SoSeparator
makeCurve()
{
  SoSeparator curveSep = new SoSeparator();

  // Set the draw style of the curve.
  SoDrawStyle drawStyle = new SoDrawStyle();
  drawStyle.lineWidth.setValue(4);
  curveSep.addChild(drawStyle);

  // Define the NURBS curve including the control points
  // and a complexity.
  SoComplexity complexity = new SoComplexity();
  SoCoordinate3 controlPts = new SoCoordinate3();
  SoNurbsCurve curve = new SoNurbsCurve();
  complexity.value.setValue(0.8f);
  controlPts.point.setValues(0, pts);
  curve.numControlPoints.setValue(13);
  curve.knotVector.setValues(0, knots);
  curveSep.addChild(complexity);
  curveSep.addChild(controlPts);
  curveSep.addChild(curve);

  return curveSep;
}