# Posts tagged ‘B-Splines’

I’ve been looking into curves for quite awhile now, along with waves and dynamics eventually hoping to combine all three. Along with these ive been trying to understand the rules of rigging especially layer and hierachal rigging. A lot of riggers i know dont undestand the idea of ‘layers’ in a rig. In simple terms its like a layer in photoshop but in rigs it free up a lot of issues if you keep aspects of a rig to a layer – so for example your base skeleton could be your first layer, then basic setup then twist, then deformation. So its more like layered relationships – deformation is a good example. If we can modularize deformation in a simple system we can use it all over the place.

Major deformations like skin simulation are outside of this, but twist, stretch, compression and bulge could be driven by one system. If we treat this system as a curve the issue arises is that its not uniform so control objects along it would bunch up so we need:

- A simplified curve, that possibly introduces horners rule (for speed)
- Uniformity across the curve (important if the tangent vectors are straight)
- The ability to overshoot the curve at both ends* (-0.5, 1.5)

*Why do we need this, well basically to allow for length between the points along the curve to be maintained, for example if we dont want the curve to compress the points along it need to overshoot the curve. This can be pretty simply acheived using a subdivision method. To keep a value at the same value i.e a length of 10 along the curve, all we do is divide this length by the curves length eg. 10/100. = 0.1 10/200 = 0.05. Problem comes in if the length of the curve is shorter than the defined length the ‘bucket’ inwhich t resides wouldnt exist. So you need to do some fiddling around. I’ll post some links accompanying this post.

Is it possible to get the length of a curve without walking along it, standard methods essentially split it into chunks and measure there total – the more chunks the better the accuracy. I’ll look into arc length and least square methods.

So currently im looking into a a scripting language to so I can develop my math stuff outside of the software and keep it a data driven as possible – currently its between JavaScript or Python. All I really care about is class definitions and handling functions.

I’m also looking into fourier synthesis, harmonic oscillations and and analog synthesis as a friend and I have a plan for an interesting tool! 🙂 Should be fun. Im also looking into oscillation and phase shift as a tool for animators – something along the lines of the ‘Wiggly Splines’ Pixars paper – I understand the basics of it, but it gets into territory dealing with basis function and new curve generalizations which in theory is possible but for max I’d either have to write sdk something else.

As to fourier synthesis, it’s really very very powerful as it allows paramaterisation of the wave form, such as quantization, rectify and full-rectifying with relative ease. Phase shift, frequency, amplitude and magnatude (terms of cosine and sine) can be handled in a deterministic fashion. Functions such as high-pass, reverb are a little more complex but if ineffect you controlling just the terms of the synthesis it might be easier.

High/low pass deal with frequency cut-off using two variables: the frequency and the attenuation: a range of q1-q10. I’m still a little confused as to how to affect the waveform as a process of the fourier – but I’m looking into it.

Ive been looking into the math behind one of the most powerful math formulas around : NURBS, or non-uniform rational-basis or bezier splines. They have an almost majestic power to TDs and riggers, along with the allusive animated pivot. Once controlled though they offer almost limitless control of a curve using a combination of the rationality of b-splines i.e the weight. And the non-uniformality of all splines i.e the spacing.

I can understand the math, but for the life of me couldnt understand the non-uniformality – its hard to actually visualize like quaternions in a way. But with my code, I started to notice something odd – i think ive been writing the ‘basis’ function with out me even knowing. In working out the percentages in which ‘t’ [0,1] lived in, i had essentially made the knot vectors nessesary for a b-spline. So basically what this means is in theory (its all in my notes atm) that i can write a b-spline basis function that neatly ties into a polynormial function. And therefore in theory Nurbs. Working out the weights its the tricky part.

The amazing thing with understanding the power polynormial function is that your curve can reside in any degree, i.e it can be cubic, quadratic on the fly. Based on the number of knot vectors – this is important as it the larger the degree the more complex the working out is. So if i have a curve of only 3 points, my degree can be 2, and so on. At the minute, im not going to expose the non-uniformality (its just exposing an array of knot vectors), so im just making an URB spline lol.

Ok so im looking into more curve math – yes I’m nuts, no im not going to show you. Most of it is over my head but im slowly understanding it, like NURB’s which I finally worked out the algorithm!! Which is kinda cool. But now for the life of me cant get my head around the recursive ‘N’ function of B-Splines i.e the Basis fn – Ni,p So:

You have p =#(1,2,3,4,5) which are you control points and t which are basically a segment in this array infact either non-uniform or uniform eg. t=#(0,.25,.5,.75,1) Now what I dont get is Ni,p because basically if t[0,1] is within you segments eg. if t = .12 then its within segment 0,1 right and so it equals 1 and if not then 0 but its always 1 unless p[0] or p[(p.count)] when it equals 0. Its basically a step fn but its always one – i dunno I there must be more to it!

Ni,0(u) = if u[i] <= u <u[i]+1 then 1 else 0 – so if u (t) is within its segment it equals 1 else 0.

edit: i think i get it.

Defining a curve segment is for a Nurbs, Cardinal or Bspline is not too hard. The key being the use of two knots and two tangents – these being derived for the cubic-bernstien-polynormials. Its defining these in the first place thats the key to the curve type.

For defining a value across several knots takes a bit more work. First we define the knots and tangents eg. knots:#(10,20,30,40) and tangents: #(#(15,18), #(23,27), #(33,38)). Next I assume a percentage value for each knot eg. #(0,33.333,66.666,100) – This is derived from the knots count.

So we have our knots, there tangents and its percentages. Next we take our input (v) value eg. 55% and find which segment where in based off the percentage – so therefore 55% is in segment 33.333 – 66.666. We’ll call these *start_p* and *end_p*.

Now we take end_p from start_p to get 33.333. So r = (end_p – start_p). We then take start_p away from our inital (v) value so (v-start_p) giving us 21.667. Now we multiply (v-start_p) by r.

r*(v-start_p) giving us 722.222 and we then divide this value by 100 (our range) to give us 65.0. So now this is input value for our polynormial but it needs to be in a range of 1 so we divide by 100 giving us 0.65.

We know the knots now, using the start_p and end_p giving us 20 and 30. Now we need the tangents; all I do is have an array of each set inside a nested array eg. #(#(15,18), #(23,27), #(33,38)) – so now we use the start_p again which is 2, so nested array 2. Then all we use is [1] and [2] of this nested array array.

*There is one bug with this system. When the input value goes past 100, or 1 depending on your scale it then falls into a new segment. So i add a new value on the end of each array to compensate.

This example is for a bspline curve, when using Nurbs, Cardinal or even straight interpolation you dont need the tangent array. But more complex math to define these tangents from the inital knots is needed. – Plus the start and end knots use slightly different math as theres no opposite tangent to define. With Nurbs you need an array of weights too.

As cox-deboor are quite simple ive started looking into cubic-bernstein-polynormials. They essentially contain 4 tangents, that can be used in defining sections of a uniform b-spline. The problem arises when defining a value along the entire b-spline – As its constructed from multiple cubic curves, and which a value along these is defined as (t) being 0 – 1.