Mathematical formula for a Nurbs curve

Does anyone know the mathematical formula that is used to construct a Nurbs curve? I found Wikipedia’s article about Nurbs curves http://en.wikipedia.org/wiki/Nurbs_curve but I didn’t know what the knot vector was, so I guessed that it started at 0 and increased by 1. Since this lead to a division by zero, I must have guessed wrong. For reference, here is the python script that I wrote to attempt to solve this problem:


def nurbs(co,w,t,order):
 def N(i,m,u):
  return f(i,m,u)*N(i,m-1,u)+g(i+1,m,u)*N(i+1,m-1,u)
 def f(i,m,u):
  return (u-i)/m
 def g(i,m,u):
  return (i+m-u)/m
 degree = len(co)
 denominator = 0
 for j in range(degree):
  denominator += N(j,order,t)*w[j]
 sum = [0.0,0.0,0.0]
 for i in range(degree):
  factor = N(i,order,t)*w[i]/denominator
  for i2 in [0,1,2]:
   sum[i2] += factor*co[i][i2]
 return sum
co = [ [-2,0,0] , [-1,-1,0] , [0,0,0] , [1,-1,0] , [2,1,0] ]
w = [1,1,1,1,1]
t = 0.2
order = 4
print nurbs(co,w,t,order)

can you elaborate what you want to do with this?

another way would be to make it has a poly line then convert to nurb curve or not depends what is the next step!

or in blender you could make directly a spline line which is a nurb curve!

salutations

It is kind of complicated to explain what I want to do with this. I have a bunch of text files that specify various things like what frame an object is keyed at what location, and what frames a strip lasts from in the NLA editor. I have a python script that reads these text files and keys the objects and adds the strips to the NLA editor. I also have nurbs curves defined in these text files and the python script creates the curves based on the defined coordinates. I want to make a character walk along these paths. I can do this in Blender 2.49b by manually adding action modifiers. I do not seem to be able to do this from Python nor in 2.6x. I wanted to do this from python so I decided that I would create a separate action based on a current action and a nurbs curve that would simulate the same effect as an action modifier in 2.49b.

I need the exact formula that Blender uses because in my text files, the curves are defined so that they would be the ideal length. For example, I might have a curve of length 12, and a walk cycle that moves 3 units per cycle. The action will then cycle exactly four times on the curve. If I used a formula other than the one that Blender uses, the curve might not have a length of 12 and then the walk cycle won’t finish at the very end of the curve. I hope this all made sense.

ok if i remember well in the code snippet PDF there is an example for path
and i think you curves are more like 3D path curves is it ?

but in any case there are already some existing API command to make different type of curves
so you don’t have to redefine a new type of curve here
just use the existing ones!

thanks

can you show the data for one typical curve in your file

is it like simple points or more as triple points like for a bezier curves ?

thanks

Here is an example from a text file that defines a nurbs curve (which is read by a python script):

<curve type=path name=0Curve loc=(13.9,26,0) rot=(0,0,-90)>
<i>13.9 26 0 1 1</i>
<i>13.65 26 0 1 1</i>
<i>13.4 26 0 1 1</i>
<i>12.8 25 0 1 1</i>
<i>12.55 25 0 1 1</i>
<i>12.3 25 0 1 1</i>
</curve>

These are simple points, not triple points like a Bezier curve.

did you look a the code snippet PDF for curve examples ?

the data looks to me like bezier curves but no triple points only ordinary bezier curve with 5 points!

example from the Curve script in code snippet


 
    # Control point coordinates
 
    coords = [
        (0.00,0.08,0.00,1.00),
        (-0.20,0.08,0.00,0.35),
        (-0.20,0.19,0.00,1.00),
        (-0.20,0.39,0.00,0.35),
        (0.00,0.26,0.00,1.00),
        (0.20,0.39,0.00,0.35),
        (0.20,0.19,0.00,1.00),
        (0.20,0.08,0.00,0.35)
    ]
 
 and an exampe for a spline data
 
Add points to spline
pointTable = [(0,0,0,0), (1,0,3,0),1,2,2,0), (0,4,0,0), (0,0,0,0)]
 

if you look into this PDF it might give you a better idea !

look to me like a bezier curve cause the name seems to be “path curve” with 5 points !
or did you set this name yourself ?

happy 2.6

I don’t know where the PDF is.

the data looks to me like bezier curves but no triple points only ordinary bezier curve with 5 points!

I’m not completely sure it was a nurbs curve. The object added with my script should be the same type as when one selects Add:Curve:Path.

look to me like a bezier curve cause the name seems to be “path curve” with 5 points !
or did you set this name yourself ?

happy 2.6

In the example I gave the “name=0Curve” causes the python script to set the name to “0Curve”. I don’t know for sure what type of curve it is and it could be a Bezier curve, but there are only single points and not triple points.

well PDF is here

http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Cookbook/Code_snippets

look at some of the scripts for curves including one for path!

your data contains 5 points so i guess it is a simple bezier curve use as a path!

sorry but still uncertain which curve type you have here !

would you happen to have a simple short file with one object having this type of curve so we can look at it from blender may be ?
it might help to identify it

or is it a curve coming from the animation fcurve or a path for a rig or a bone location ?

thanks

I attached a .blend file with a curve generated by my python script. It is this type of curve that I want to be able to describe mathematically.

Attachments

curve_test_20120211.blend (150 KB)

here a script for bezier curve from the code snippet PDF file as example


#----------------------------------------------------------
# File curve.py
#----------------------------------------------------------
import bpy
def createBevelObject():
    # Create Bevel curve and object
    cu = bpy.data.curves.new('BevelCurve', 'CURVE')
    ob = bpy.data.objects.new('BevelObject', cu)
    bpy.context.scene.objects.link(ob)
    # Set some attributes
    cu.dimensions = '2D'
    cu.resolution_u = 6
    cu.twist_mode = 'MINIMUM'
    ob.show_name = True
    # Control point coordinates
    coords = [
        (0.00,0.08,0.00,1.00),
        (-0.20,0.08,0.00,0.35),
        (-0.20,0.19,0.00,1.00),
        (-0.20,0.39,0.00,0.35),
        (0.00,0.26,0.00,1.00),
        (0.20,0.39,0.00,0.35),
        (0.20,0.19,0.00,1.00),
        (0.20,0.08,0.00,0.35)
    ]
    # Create spline and set control points
    spline = cu.splines.new('NURBS')
    nPointsU = len(coords)
    spline.points.add(nPointsU)
    for n in range(nPointsU):
        spline.points[n].co = coords[n]
    # Set spline attributes. Points probably need to exist here.
    spline.use_cyclic_u = True
    spline.resolution_u = 6
    spline.order_u = 3
    return ob
 
def createCurveObject(bevob):
    # Create curve and object
    cu = bpy.data.curves.new('MyCurve', 'CURVE')
    ob = bpy.data.objects.new('MyCurveObject', cu)
    bpy.context.scene.objects.link(ob)
    # Set some attributes
    cu.bevel_object = bevob
    cu.dimensions = '3D'
    cu.use_fill_back = True
    cu.use_fill_front = True
    ob.show_name = True
    # Bezier coordinates
    beziers = [
        ((-1.44,0.20,0.00), (-1.86,-0.51,-0.36), (-1.10,0.75,0.28)),
        ((0.42,0.13,-0.03), (-0.21,-0.04,-0.27), (1.05,0.29,0.21)),
        ((1.20,0.75,0.78), (0.52,1.36,1.19), (2.76,-0.63,-0.14))
    ]
    # Create spline and set Bezier control points
    spline = cu.splines.new('BEZIER')
    nPointsU = len(beziers)
    spline.bezier_points.add(nPointsU)
    for n in range(nPointsU):
        bpt = spline.bezier_points[n]
        (bpt.co, bpt.handle_left, bpt.handle_right) = beziers[n]
    return ob
 
def run(origin):
    bevob = createBevelObject()
    bevob.location = origin
    curveob = createCurveObject(bevob)
    curveob.location = origin
    bevob.select = False
    curveob.select = True
    bpy.ops.transform.translate(value=(2,0,0))
    return
if __name__ == "__main__":
    run((0,0,0))
 
 
 

you can upload in text editor and run it then look into the viewport

it looks that there is an error on this script
you can remove the fill back line i guess

and there is also a bevel curve added to the curve which you don’t really need

hope it helps

salutations

Thank you for your help, but that isn’t quite what I wanted. The Wikipedia article at http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization has something similar to what I want, but it looks like those formulas only deal with curves where the “Order U” setting under “Curve Tools” is set to the total number of points in the curve. I want to be able to describe the curve mathematically when “Order U” is less than the total number of points on the curve (usually I have Order U = 4).