<p>I will suggest something for the rotational part but I do not know how fast it is. Assume you have a 3D coordinate system centered at the pivoting point of the joint and fixed with respect to one of the bars that meet at the joint. The other bar moves in this coordinate system always attached the origin of the system. So its motion is a curve on a sphere centered at the joint's pivoting point and radius the bar's length <span class="math-container">$l$</span>. Assume you have a sequence of positions <span class="math-container">$\vec{x}_0, \, \vec{x}_1, \, \vec{x}_2, \, ..., \vec{x}_m$</span> of the moving bar with respect to this system. Recall the bar has length <span class="math-container">$l$</span>. Then calculate the cross products: 
<span class="math-container">$$\vec{n}_j = \vec{x}_0 \times \vec{x}_j$$</span> and the cosine of the angle <span class="math-container">$$c_j = \cos(\theta_{j}) =  \frac{1}{l^2} \, (\vec{x}_0 \cdot \vec{x}_j) $$</span> as well as the magnitude <span class="math-container">$\|\vec{n}_j\| = \sqrt{ (\vec{n}_{j} \cdot \vec{n}_j) }$</span>. Normalize 
<span class="math-container">$$\vec{N}_j = \frac{\vec{n}_j}{\|\vec{n}_j\|}$$</span><br>
So now you have the list of pairs 
<span class="math-container">$$\big(\vec{N}_1, \, c_1\big), \, \big(\vec{N}_2, \, c_2\big), \, ... ,\, \big(\vec{N}_m, \, c_m\big)$$</span>
Apply a cubic or some other appropriate spline interpolation to the list of data. The result is the pair of smooth families
<span class="math-container">$$\vec{N}(t), \, c(t)$$</span>
Use  <a href="https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula" rel="nofollow noreferrer">Rodrigues' rotation formula</a> to obtain the smooth family of rotation matrices
<span class="math-container">$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$</span> where <span class="math-container">$\hat{N}(t) = \big( \vec{N}(t) \times \cdot \big) $</span> is the three by three skew symmetric matrix that acts on a vector <span class="math-container">$\vec{x}$</span> by
<span class="math-container">$\hat{N}(t)\, \vec{x} = \vec{N}(t) \times \vec{x}$</span>. Notice the presence of the <span class="math-container">$\pm$</span> sign, which is negative when the angle between the vectors <span class="math-container">$\vec{x}_0$</span> and <span class="math-container">$\vec{x}_j$</span> starts to exceed <span class="math-container">$180^{\circ}$</span>. This really depends on the range of motion of the joint. Anyway, then the joint moves smoothly by 
<span class="math-container">$$\vec{x}(t) = U(t)\, \vec{x}_0$$</span> and at each moment of time <span class="math-container">$t_j$</span> for which
<span class="math-container">$c(t_j) = c_j$</span> and <span class="math-container">$\vec{N}(t_j) = \vec{N}_j$</span> due to the interpolation scheme we get
<span class="math-container">$$\vec{x}_j = U(t_j)\, \vec{x}_0$$</span>
All of this can be done with quaternions, the idea is analogous. It is up to you.  </p>

<p><strong>The case of framed joint:</strong> If you have one coordinate system attached firmly to the first bar of the joint and a second coordinate system attached firmly to the second bar of the joint (both have origin at the pivoting point of the joint, i.e. I am ignoring translations), then the position of the second bar with respect to the coordinate system of the first one is described by the position of the second coordinate system with respect to the first. Then, if <span class="math-container">$\vec{u}_1, \, \vec{u}_2, \vec{u}_3$</span> are the unit orthogonal column-vectors of the second coordinate system written with respect to the first coordinate system, the orthogonal matrix that maps the first system to the second is <span class="math-container">$U = [\vec{u}_1 \,\, \vec{u}_2 \,\, \vec{u}_3]^T$</span> (the vectors are 3 x 1 columns of coordinates of the basis vectors of the second coordinate system with respect to the first coordinate system). Consequently, in this case (of framed joint motion) you may actually have a sequence of orthogonal matrices, describing the positions of the second system relative to the first at different times:
<span class="math-container">$U_1, \, U_2, \, ..., \, U_m$</span>. In this case, calculate the skew symmetric matrices <span class="math-container">$$\hat{n}_j = \frac{1}{2} \big( U_j - U_j^T \big)$$</span> and calculate the traces
<span class="math-container">$$\|\hat{n}_j\| = \sqrt{ - \frac{1}{2} \, \text{trace}\big(\hat{n}_j^2\big) }$$</span> Then 
<span class="math-container">$$\hat{N}_j = \left(\frac{1}{\|\hat{n}_j\|}\right) \, \hat{n}_j$$</span> is a skew symmetric matrix with the property that there exists a unique unit vector <span class="math-container">$\vec{N}_j$</span> such that for any vector <span class="math-container">$\vec{x}$</span>
<span class="math-container">$$\hat{N}_j \, \vec{x} = \vec{N}_j \times \vec{x}$$</span>
and 
<span class="math-container">$$c_j = \cos(\theta_j) = \frac{\text{trace}(U_j) - 1}{2}$$</span>
As before, you have the list of pairs 
<span class="math-container">$$\big(\vec{N}_1, \, c_1\big), \, \big(\vec{N}_2, \, c_2\big), \, ... ,\, \big(\vec{N}_m, \, c_m\big)$$</span> or equvialently the list of pairs (whichever works better for you, although they are equivalent)
<span class="math-container">$$\big(\hat{N}_1, \, c_1\big), \, \big(\hat{N}_2, \, c_2\big), \, ... ,\, \big(\hat{N}_m, \, c_m\big)$$</span>
Apply again a cubic or some other spline interpolation to either of the lists of data. The result is the pair of smooth families
<span class="math-container">$$\hat{N}(t), \, c(t)$$</span>
Just as before,  <a href="https://en.wikipedia.org/wiki/Rotation_matrix" rel="nofollow noreferrer">by the properties of rotational matrices</a>, you obtain the smooth family of rotation matrices
<span class="math-container">$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$</span> This <span class="math-container">$U(t_j) = U_j$</span> for all <span class="math-container">$j = 1, .., m$</span>.</p>

CC BY-SA 4.0
2019-05-29T17:24:02.990Z
2019-05-30T00:00:07.483Z
2019-05-30T00:00:07.483Z
Futurologist
<p>The simplest way is to use n-way nlerp (normalized lerp) instead. It does mean slight inaccuracies in the blend but careful (manual) tweaking of the weights and good key pose selection can take care of that.</p>

<p><code>nlerp</code> will approximate <code>slerp</code> when the key poses are close to each other. So you will very likely get away with not tweaking the weights at all in most cases.</p>

<p>Also keep in mind that not all bones need to be blended the same way. </p>

CC BY-SA 4.0
2019-05-29T11:39:18.000Z
So, if I have two poses like "head bow" and "hands up", they are not really close and `nlerp` will produce bad results?
Charlie
CC BY-SA 4.0
2019-05-29T11:58:48.683Z
manually create intermediary poses that look better and path the weights between them.
ratchet freak
CC BY-SA 4.0
2019-05-29T10:01:13.723Z
2019-05-29T11:59:25.727Z
2019-05-29T11:59:25.727Z
ratchet freak
<p>I <a href="https://stackoverflow.com/a/5814107/1305036">found out</a> that I should use spherical linear interpolation to blend two poses of a joint. I cannot find what to do if I have hundreds of poses to blend except applying the SLERP iteratively.</p>

<p>What are the default methods to interpolate between multiple skeletal poses? For example, which algorithms are used by Unity3D, UE4, 3DS Max, Maya, etc? How do they solve the problem of rotation non-commutativity?</p>

<p>I'm looking for an analytical well-differentiable (with respect to blending weights) formula if one exists.</p>

CC BY-SA 4.0
2019-05-28T07:10:29.790Z
If you don't want sequential interpolation, but actual interpolation between 100 poses with 100 parameters, then you have to define a 100 dimensional manifold which would serve as a metric of "how close" two poses are, then you simply take a convex linear combination of the parameters on that manifold and find the corresponding point. It's a non-trivial problem without further constraints.
lightxbulb
<transformations><mathematics><interpolation><blending>
How to calculate interpolation between multiple skeleton poses?
Charlie
# How to calculate interpolation between multiple skeleton poses?

(Asked by: username_0 on 2019-05-27)

I [found out](https://stackoverflow.com/a/5814107/1305036) that I should use spherical linear interpolation to blend two poses of a joint. I cannot find what to do if I have hundreds of poses to blend except applying the SLERP iteratively.

What are the default methods to interpolate between multiple skeletal poses? For example, which algorithms are used by Unity3D, UE4, 3DS Max, Maya, etc? How do they solve the problem of rotation non-commutativity?

I'm looking for an analytical well-differentiable (with respect to blending weights) formula if one exists.

**Tags:** transformations, mathematics, interpolation, blending

> **Comments:**
> **username_1**: If you don't want sequential interpolation, but actual interpolation between 100 poses with 100 parameters, then you have to define a 100 dimensional manifold which would serve as a metric of "how close" two poses are, then you simply take a convex linear combination of the parameters on that manifold and find the corresponding point. It's a non-trivial problem without further constraints.  

---

## 2 answers

### Answer by username_2 on 2019-05-29. Score: 1

I will suggest something for the rotational part but I do not know how fast it is. Assume you have a 3D coordinate system centered at the pivoting point of the joint and fixed with respect to one of the bars that meet at the joint. The other bar moves in this coordinate system always attached the origin of the system. So its motion is a curve on a sphere centered at the joint's pivoting point and radius the bar's length $l$. Assume you have a sequence of positions $\vec{x}\_0, \, \vec{x}\_1, \, \vec{x}\_2, \, ..., \vec{x}\_m$ of the moving bar with respect to this system. Recall the bar has length $l$. Then calculate the cross products:
$$\vec{n}\_j = \vec{x}\_0 \times \vec{x}\_j$$ and the cosine of the angle $$c\_j = \cos(\theta\_{j}) = \frac{1}{l^2} \, (\vec{x}\_0 \cdot \vec{x}\_j) $$ as well as the magnitude $\|\vec{n}\_j\| = \sqrt{ (\vec{n}\_{j} \cdot \vec{n}\_j) }$. Normalize
$$\vec{N}\_j = \frac{\vec{n}\_j}{\|\vec{n}\_j\|}$$  
So now you have the list of pairs
$$\big(\vec{N}\_1, \, c\_1\big), \, \big(\vec{N}\_2, \, c\_2\big), \, ... ,\, \big(\vec{N}\_m, \, c\_m\big)$$
Apply a cubic or some other appropriate spline interpolation to the list of data. The result is the pair of smooth families
$$\vec{N}(t), \, c(t)$$
Use [Rodrigues' rotation formula](https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula) to obtain the smooth family of rotation matrices
$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$ where $\hat{N}(t) = \big( \vec{N}(t) \times \cdot \big) $ is the three by three skew symmetric matrix that acts on a vector $\vec{x}$ by
$\hat{N}(t)\, \vec{x} = \vec{N}(t) \times \vec{x}$. Notice the presence of the $\pm$ sign, which is negative when the angle between the vectors $\vec{x}\_0$ and $\vec{x}\_j$ starts to exceed $180^{\circ}$. This really depends on the range of motion of the joint. Anyway, then the joint moves smoothly by
$$\vec{x}(t) = U(t)\, \vec{x}\_0$$ and at each moment of time $t\_j$ for which
$c(t\_j) = c\_j$ and $\vec{N}(t\_j) = \vec{N}\_j$ due to the interpolation scheme we get
$$\vec{x}\_j = U(t\_j)\, \vec{x}\_0$$
All of this can be done with quaternions, the idea is analogous. It is up to you.

**The case of framed joint:** If you have one coordinate system attached firmly to the first bar of the joint and a second coordinate system attached firmly to the second bar of the joint (both have origin at the pivoting point of the joint, i.e. I am ignoring translations), then the position of the second bar with respect to the coordinate system of the first one is described by the position of the second coordinate system with respect to the first. Then, if $\vec{u}\_1, \, \vec{u}\_2, \vec{u}\_3$ are the unit orthogonal column-vectors of the second coordinate system written with respect to the first coordinate system, the orthogonal matrix that maps the first system to the second is $U = [\vec{u}\_1 \,\, \vec{u}\_2 \,\, \vec{u}\_3]^T$ (the vectors are 3 x 1 columns of coordinates of the basis vectors of the second coordinate system with respect to the first coordinate system). Consequently, in this case (of framed joint motion) you may actually have a sequence of orthogonal matrices, describing the positions of the second system relative to the first at different times:
$U\_1, \, U\_2, \, ..., \, U\_m$. In this case, calculate the skew symmetric matrices $$\hat{n}\_j = \frac{1}{2} \big( U\_j - U\_j^T \big)$$ and calculate the traces
$$\|\hat{n}\_j\| = \sqrt{ - \frac{1}{2} \, \text{trace}\big(\hat{n}\_j^2\big) }$$ Then
$$\hat{N}\_j = \left(\frac{1}{\|\hat{n}\_j\|}\right) \, \hat{n}\_j$$ is a skew symmetric matrix with the property that there exists a unique unit vector $\vec{N}\_j$ such that for any vector $\vec{x}$
$$\hat{N}\_j \, \vec{x} = \vec{N}\_j \times \vec{x}$$
and
$$c\_j = \cos(\theta\_j) = \frac{\text{trace}(U\_j) - 1}{2}$$
As before, you have the list of pairs
$$\big(\vec{N}\_1, \, c\_1\big), \, \big(\vec{N}\_2, \, c\_2\big), \, ... ,\, \big(\vec{N}\_m, \, c\_m\big)$$ or equvialently the list of pairs (whichever works better for you, although they are equivalent)
$$\big(\hat{N}\_1, \, c\_1\big), \, \big(\hat{N}\_2, \, c\_2\big), \, ... ,\, \big(\hat{N}\_m, \, c\_m\big)$$
Apply again a cubic or some other spline interpolation to either of the lists of data. The result is the pair of smooth families
$$\hat{N}(t), \, c(t)$$
Just as before, [by the properties of rotational matrices](https://en.wikipedia.org/wiki/Rotation_matrix), you obtain the smooth family of rotation matrices
$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$ This $U(t\_j) = U\_j$ for all $j = 1, .., m$.


---

### Answer by username_3 on 2019-05-29. Score: 0

The simplest way is to use n-way nlerp (normalized lerp) instead. It does mean slight inaccuracies in the blend but careful (manual) tweaking of the weights and good key pose selection can take care of that.

`nlerp` will approximate `slerp` when the key poses are close to each other. So you will very likely get away with not tweaking the weights at all in most cases.

Also keep in mind that not all bones need to be blended the same way.

> **Comments:**
> **username_0**: So, if I have two poses like "head bow" and "hands up", they are not really close and `nlerp` will produce bad results?  
> **username_3**: manually create intermediary poses that look better and path the weights between them.  

---

