Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

I use a Catmull-Rom spline, each section built from a set of cubic functions p = x(t), y(t), z(t).

I was looking at Frenet Formulas but it's not working as desired... . Generating T = (x'(t),y'(t),z'(t)) is easy, using B = (x''(t),y''(t),z''(t)) isn't doing what I expect... T and B are not orthogonal.

Looking at it more closely I'm not convinced this is what should happen. Am I misunderstanding the math, or misunderstanding what F-S is for?

As a concrete example let's say:

x(t) = 2t^3 + t^2 - 3t + 6
y(t) = t^3 - 2t^2 + 4t
z(t) = -3t^3 + 4t^2 + 2t - 9

Where 0<=t<=1.

share|improve this question
You're supposed to normalize your derivatives first (because your spline is not unit-speed parametrized); and then shift the vectors forming the Frenet frame to the actual point on the curve. –  Guess who it is. Jan 30 '12 at 14:13
@J.M. - that sounds good but is a bit over my head; could someone elaborate on that in a full answer? Is normalizing over t a required step for this to work, or an extra step that should be done simply for better spline behavior? –  Mr. Boy Jan 30 '12 at 14:23
Actually, you really should be looking at this section of the wiki entry you linked to; they are doing precisely the normalization that I was alluding to. You are familiar with the concept of a vector norm, yes? –  Guess who it is. Jan 30 '12 at 14:32
@J.M. do you simply mean normalizing a single vector to unit length? If so then yes... but when you take a cross-product this would change only the magnitude of the result, not its direction; hence my confusion. I'll add a specific example to my question. –  Mr. Boy Jan 30 '12 at 14:58
Right; you do that normalization to the derivatives of each piece of your spline. For the first derivative, normalizing nets you the tangent vector; for the second derivative, normalizing yields the binormal vector. Cross the two, and you have the normal vector. Since these vectors start from the origin, a shift's necessary. –  Guess who it is. Jan 30 '12 at 15:04

2 Answers 2

up vote 3 down vote accepted

Alright, I'll work on two of the vectors; I'll leave the third one to you.

You have the vector-valued function

$$\mathbf c(t)=\begin{pmatrix}2t^3 + t^2 - 3t + 6\\t^3 - 2t^2 + 4t\\-3t^3 + 4t^2 + 2t - 9\end{pmatrix}$$

The first two derivatives are easily done:

$$\mathbf c^\prime(t)=\begin{pmatrix}6t^2+2t-3\\3t^2-4t+4\\-9t^2+8t+2\end{pmatrix}$$

$$\mathbf c^{\prime\prime}(t)=\begin{pmatrix}12t+2\\6t-4\\8-18t\end{pmatrix}$$

To get the tangent vector, we first get the norm of $\mathbf c^\prime(t)$:

$$\begin{align*} \|\mathbf c^\prime(t)\|&=\sqrt{(6t^2+2t-3)^2+(3t^2-4t+4)^2+(-9t^2+8t+2)^2}\\ &=\sqrt{126t^4-144t^3+36t^2-12t+29} \end{align*}$$

and that is the thing we divide $\mathbf c^\prime(t)$ with:

$$\mathbf T(t)=\frac{\mathbf c^\prime(t)}{\|\mathbf c^\prime(t)\|}=\frac1{\sqrt{126t^4-144t^3+36t^2-12t+29}}\begin{pmatrix}6t^2+2t-3\\3t^2-4t+4\\-9t^2+8t+2\end{pmatrix}$$

To get the binormal vector, we first cross $\mathbf c^\prime(t)$ and $\mathbf c^{\prime\prime}(t)$:

$$\mathbf c^\prime(t)\times \mathbf c^{\prime\prime}(t)=\begin{pmatrix}12t^2-84t+40\\66t^2-30t+28\\30t^2-66t+4\end{pmatrix}$$

normalize that result,

$$\begin{align*} \|\mathbf c^\prime(t)\times \mathbf c^{\prime\prime}(t)\|&=\sqrt{(12t^2-84t+40)^2+(66t^2-30t+28)^2+(30t^2-66t+4)^2}\\ &=24(225t^4-414t^3+717t^2-372t+100) \end{align*}$$

and assembling the binormal vector's a snap:

$$\mathbf B(t)=\frac{\mathbf c^\prime(t)\times \mathbf c^{\prime\prime}(t)}{\|\mathbf c^\prime(t)\times \mathbf c^{\prime\prime}(t)\|}=\frac1{\sqrt{24(225t^4-414t^3+717t^2-372t+100)}}\begin{pmatrix}12t^2-84t+40\\66t^2-30t+28\\30t^2-66t+4\end{pmatrix}$$

Computing the normal vector, I leave to you. But, here's a nice bonus you might appreciate:

Frenet frame for a cubic curve

share|improve this answer
Very cool thanks. My confusion turned out to be that I was thinking of normalizing the result at a given value of t, rather than normalizing the equation itself. –  Mr. Boy Jan 30 '12 at 17:21

The reason your formula for $\mathbf{b}$ (shouldn't it be $\mathbf{n}$, anyway?) doesn't work is, that your curve is not parameterized by arc-length. The formula


only holds for an arc-length parameterization (notice the $s$ usually used for the arc-length parameter), in which also $\mathbf{t}(s)=\mathbf{x}'(s)$ is already of unit length.

This doesn't work for a general parameter $t$. You are right in that normalizing the operands doesn't change the direction of a cross product. But whereas for $\mathbf{t}(t)=\frac{\mathbf{x}'(t)}{\|\mathbf{x}'(t)\|}$ it just comes down to normalization, $\mathbf{x}\verb|"|(t)$ points into a completely different direction than $\mathbf{x}\verb|"|(s)$, making $\frac{\mathbf{x}\verb|"|(t)}{\|\mathbf{x}\verb|"|(t)\|}$ a completely different vector than $\mathbf{n}$. This is because we need not just derive $\mathbf{x}'(t)$, but $\frac{\mathbf{x}'(t)}{\|\mathbf{x}'(t)\|}$.

So for a general parameter $t$, the formulas are actually given by:


$\mathbf{n}(t)=\frac{\mathbf{x}'(t)\times(\mathbf{x}\verb|"|(t)\times\mathbf{x}'(t))}{\|\mathbf{x}'(t)\times(\mathbf{x}\verb|"|(t)\times\mathbf{x}'(t))\|} = \mathbf{b}(t)\times\mathbf{t}(t)$

$\mathbf{b}(t)=\frac{\mathbf{x}'(t)\times\mathbf{x}\verb|"|(t)}{\|\mathbf{x}'(t)\times\mathbf{x}\verb|"|(t)\|} = \mathbf{t}(t)\times\mathbf{n}(t)$

Making it practically easiest to just compute $\mathbf{t}$ and $\mathbf{b}$ and compute $\mathbf{n}$ by crossing these (keep an eye on the order of operands, though, as you know $\times$ is not commutative).

And additionally you have to keep in mind, that a Catmull-Rom spline is generally only $C^1$ at the interpolated points (where two splines connect), which means its second derivative $\mathbf{x}\verb|"|$ (and thus its Frenet-frame) doesn't need to be continuous at these points (though it's of course continuous inside the individual splines, as they're cubi splines). But I don't know if that is a problem for you.

share|improve this answer
Good catch about x" being non-continuous. I'm not sure if it's an issue yest, is there a quick fix like dropping in a different piecewise function or does it get complicated? –  Mr. Boy Jan 30 '12 at 22:02
@John Don't know. It never was a problem for me. If I ever need C2 continuity on the whole curve, I just take a cubic B-Spline. Otherwise you just have to be sure to restrict the relevant interval to a single spline in every computation that needs a continuous 2nd derivative (e.g. Newton-based minimization or examination of curvature development). –  Christian Rau Jan 30 '12 at 23:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.