Chordal Catmull-Rom Splines

1.5k views Asked by At

I've been working on getting Catmull-Rom splines working for a side project and am having difficulty getting it to do what I need. I tried the following two implementations and both didn't work for me, and I was unable to track down any errors in my code relative to theirs (which I have to assume has been tested). I'll call theirs the "ABC" solution:

Catmull-rom curve with no cusps and no self-intersections

https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline

I then implemented the following solution (that I call the "Matrix" solution) and it did work using the edited version 3 posts down: https://www.opengl.org/discussion_boards/showthread.php/159518-catmull-rom-spline

However, this Matrix solution just implements Catmull-Rom with a 0.5 'a' value built into the matrix. I'd like to get Chordal working, and thus I need 'a' == 1.

Given that my solution for the ABC version was causing problems, I've attempted to use the matrix here (http://algorithmist.net/docs/catmullrom.pdf) to pass in my own 'a'. Here's the original 0.5 code followed by my modified code that's passing in a user specified 'a'.

Original Code:

float u2 = u * u;
float u3 = u2 * u;

return ((2 * x1) + 
       (-x0 + x2) * u + 
       (2*x0 - 5*x1 + 4*x2 - x3) * u2 + 
       (-x0 + 3*x1 - 3*x2 + x3) * u3) * 0.5f;

Modified Code:

float u2 = u * u;
float u3 = u2 * u;

static float a = 0.5f;

return ((1.0f * x1) + 
       ((-a*x0) + (a*x2)) * u + 
       ((2.0f*a)*x0 + (a-3.0f)*x1 + (3.0f-(2.0f*a))*x2 + (-a*x3)) * u2 + 
       ((-a*x0) + (2.0f-a)*x1 + (a-2.0f)*x2 + (a*3.0f)) * u3) * 0.5f;

This of course doesn't work. However, I'm not seeing why. At the bottom of page 4 in the pdf it shows the matrix with 'a' in it. I've substituted that in the above modified code and triple checked it, yet the spline is screwed up. It should have given me the same answer. What's doubly confusing is that his results on page 5 take that resulting matrix and multiply it by 0.5 which drops all the /2's off the matrix entries. The final matrix uses THESE values, but the original matrix on page 4 is not 0.5 * matrix, it's just "matrix". Why was this 0.5 arbitrarily added and why does everything break without it?

Anyway, does anyone know what I might be doing wrong with my equation? Can I use this matrix form to pass in my own 'a' from 0-1 and create uniform, centripetal and chordal splines or will I have to use the ABC form?

Thanks in advance!

1

There are 1 answers

1
fang On

I think the matrix with 'a' in page 4 of the pdf file is still for uniform Catmull-Rom (CR) spline. The parameter 'a' is the tension parameter. In the Wiki page (https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline), it also use a 'alpha' for controlling the knot sequences assigned to each point. Don't confuse the tension parameter 'a' with this 'alpha'.

A "standard" uniform CR spline will have alpha=0.0 (which will result in a=0.5). You will need to use alpha=1.0 for chordal CR spline and alpha=0.5 for centripetal CR spline. Their corresponding matrix form will both involve the knot sequences of the points. So, using a=1.0 in the matrix form for uniform CR spline will not result in a chordal CR spline but a uniform CR spline with stronger tangents at the data points, which typically will cause undesired spline shape.