Warning: this page is hasty and incomplete.
NURBS stands for "Non-Uniform Rational B-Splines".
Some j wiki pages use NURBS but they do not include any documentation: Studio/OpenGL/Teapot and Studio/OpenGL/BraidKnot
To understand NURBS I should first understand Bezier curves and B-Splines.
Here's an example of using a one-dimensional (rank zero coordinates) Bezier curve
Bz=: [ +/@:* (i. ! <:)@#@[ * ] (^~/~ * -.@[ ^~/~ |.@]) i.@#@[ require'plot' _10 20 _20 10 Bz 0.01*i.101
The domain of Bezier curves is real numbers 0 through 1. The range of Bezier curves over that domain is {.x through {:x. Look at some plots for further insight.
TODO: Bezier curves can be subdivided into a sequence of Bezier curves. This requires a treatment of Bezier curves with arbitrary end points.
Bez=:2 :'[ Bz ((n-m) %~ m -~ ])'
The domain of m Bez n is m through n.
TODO: implement b-splines in one dimension (NURBS seem to imply 3 or 4 dimensional coordinates with the fourth value in each coordinate being 1 in some expressions), then go back and do all of these for arbitrary dimensions (rank 1 coordinates)
B-Splines have a basis from the Cox de Boor formula:
Cox_deBoor=:4 : 0"1 0
NB. x: knots
N=.,:(x <: y) *. 1 |. y < x
for_p. }.i.(#x)-I.{.N do.
Ni=. {:N
xp1=. (p+1)|. x
N=.N,(Ni*(x-y)%x-p|.x) + (}.Ni,0)*(xp1-y)%xp1-1|.x
end.
)
NB. example use:
1 2 3 4 5 Cox_deBoor 1.5
1 2 3 4 5 Cox_deBoor 3.5Informally, the values in this matrix represent interpolation of the previous rows values for the given value of y.
That's a rather awkward expression, and I should clean it up (for example, note that values rotated around the end by |. do not matter here as they will always be multiplied by 0).
Uniform B-Splines have uniform spacing between the knots. In other words, x would be replaced by x0 + (x1-x0) * i.n where x0 and x1 are the first two knot values.
Cox_deBoorU=:4 :0"1 0 'x0 x1 n'=. x d=.x1-x0 (x0+d*i.n+<.(y-x0)%d) Cox_deBoor y ) 1 2 7 Cox_deBoorU 6.5 8.5 NB. seven row Cox de Boor bases
This result looks slightly odd, and seems to conflict with my informal description, above.
1 2 7 Cox_deBoorU 5
However, when compared with nearby values, that result seems appropriate:
1 2 7 Cox_deBoorU 4.9 5 5.1
