Centripetal Catmull-Rom

For spline path, the catmull-rom spline has an issue of creating loop around the knots when the control points are close to one another. The centripetal catmull-rom can fix this behaviour. It would be great to include the centripetal catmull-rom in the spline class.


1 Like

For better illustration a pic from wiki:

1 Like

Are you working on this?

As otherwise I’d like do add this feature.

Hi Sirop, Please do go ahead with this.

I haven’t change the SplinePath apart from making some functions public.
Vector<WeakPtr> GetControlPoints();
Spline GetSpline();
void CalculateLength();

I also commented out CalculateLength() in OnMarkedDirty function. As I’m manually calling it, when I need to update the Length.

You might want to look at improving the CalculateLength() function so that we can change the number of increment in the calculation. This need to update in the DebugDraw function as well…
What I would do is create a const number of segment = 20 to each control point added. This way if we have more control points, we would have more segments to remove a path interpolate issue. Or maybe add a public function to override this value and call CalculateLength() function when update the changes.

I do not have a clear understanding of this quote. Do you mean precalculation of length for about 20 intervals/segments around each control point?

Anyway I’ll begin on the weekend.

No, that would be hard and will cause larger changes in the code base, and possibly reduce the performance.

What I mean is. The number of segment between 0 and 1 in the interpolation Should be equivalent to:

(NoControlPoints -1)*NoSegments instead of what hard coded like currently. (e.g. for (float f = 0.000f; f <= 1.000f; f += 0.001f)

If you are committed to big changes then you might want to add flags for different modes of interpolation for the segments.

Best regards


I am looking around for different implementations of CatMull-Rom and thus I came across
https://github.com/ejmahler/SplineLibrary . This lib makes a difference between “looped” ( P0=Pn)
and “non-looped” (P0!=Pn) splines for each spline type.

Have your tried out anything like “looped” splines with the present code of Urho3D or with your own code?
Do you think this differentiation between “looped” and “non-looped” splines is indispensable?

Hi Sirop,

I’m currently only using CATMULL_ROM_FULL_CURVE. Since it is easy to do both normal catmull-rom and catmull-rom full curve from this Urho implementation.

  1. For normal catmull-rom I just move the first point to the location of the SplinePath node.

  2. To make it a full path catmull-rom, I would just add the last point at the location of the first point. The SplinePath animation update need to update the interpolation for re-loop if traveled_ > 1 then traveled_ = traveled_ - int(traveled_).

Beware that Urho use a uniform interpolation. If object travelling at constant speed, It will not display correctly on the spline.

Best regards

Well, it took some time in my case as i was destrated by so many other things.

The code is pretty raw, as I tried to break as little as possible of the present Spline API.

The actual Catmull Rom spline calculation behind

            return CalculateCatmullRomC(knots[originIndex].GetVector3(), knots[originIndex + 1].GetVector3(),
                 knots[originIndex + 2].GetVector3(), knots[originIndex + 3].GetVector3(), t, t2, t3);

is lent from https://stackoverflow.com/a/23980479/4599792 .

Only valid for Vector3 so far as I was too lazy…

The second factor of the exponent in

float dt0 = powf((p0-p1).LengthSquared(), 0.5f * 0.5f);
float dt1 = powf((p1-p2).LengthSquared(), 0.5f * 0.5f);
float dt2 = powf((p2-p3).LengthSquared(), 0.5f * 0.5f);

is actually the so called ‘alpha’ parameter of CatMull-Rom spline. You can change it continously from 0.0 (uniform case) over 0.5 (cetripetal case as shown here) and up to 1.0 (chordal case).

The project is organized as a Qt project:
https://github.com/sirop/Urho3d_CatmullRomCentripetal ,
Can be compiled the usual way as a Sample of Urho3D. To do this delete Qt *.pro file and follow Urho3D docs.

And a pic:
If you zoom into the region between P1 und P2 , you’ll see no cusps or loops.
Just the way it schould be with alpha=0.5 .