2

I have two vectors $\vec a$ and $\vec b$ in 3d space. Both of these vectors has length (magnitude) 1 and begin from the origin, so $\vec a$ can be turned into $\vec b$ by a unit quaternion $q$:

$$\vec b = q^{-1} \vec a q$$

So the question is: how can I get this quaternion $q$ that turns vector $\vec a$ into vector $\vec b$? Speaking about why I need this, actually the problem's to rotate a bunch of points, while $\vec a$ and $\vec b$ just set the rotation. And I had to do this exactly using quaternion math, not matrixes or angles.

Any help on how I can solve this would be appreciated, but the better way is to get a rotation quaternion directly without finding a matrix and converting it into a quaternion. Thank in advance!

NOTE: The angle between these two vectors can't be greater than 90°.

  • You wrote And I had to do this exactly using quaternion math, not matrixes or angles. but when presented with two answers, one which does and one which doesn't, you accepted the one that doesn't. Not very nice! – rschwieb Aug 31 '22 at 11:14
  • Think any two vectors ending on the surface of the unit sphere, on the same latitude (with respect to some system of spherical coordinates). You can then simply rotate about the axis connecting the poles of that sphere. In fact, there are infinitely many different rotations taking a given vector to another. And infinitely many quaternions that work. Just pick any plane through the end points of the two vectors, and use the intersection of that plane and the sphere as the latitude. – Jyrki Lahtonen Sep 01 '22 at 15:14

2 Answers2

2

I'll use $\hat{a}$ and $\hat{b}$ for the two unit vectors ($\lVert\hat{a}\rVert = 1$ and $\lVert\hat{b}\rVert = 1$. The axis of rotation is then their cross product, and the cosine of the angle is their dot product: $$\begin{aligned} \vec{n} &= \hat{a} \times \hat{b} \\ \hat{n} &= \frac{\vec{n}}{\lVert\vec{n}\rVert} \\ \cos\theta &= \hat{a} \cdot \hat{b} = c, \quad 0 \le \theta \le 180° \\ \cos\frac{\theta}{2} &= \sqrt{\frac{1 + c}{2}} \\ \sin\frac{\theta}{2} &= \sqrt{\frac{1 - c}{2}} \\ \end{aligned}$$ An unit quaternion $\mathbf{q} = (r; i, j, k)$ describes rotation around unit axis vector $\hat{n} = (n_x, n_y, n_z)$ by angle $\theta$, when $$\left\lbrace ~ \begin{aligned} \mathbf{q}_r &= \cos\frac{\theta}{2} = \sqrt{\frac{1 + c}{2}} \\ \mathbf{q}_i &= n_x \sin\frac{\theta}{2} = n_x \sqrt{\frac{1 - c}{2}} \\ \mathbf{q}_j &= n_y \sin\frac{\theta}{2} = n_y \sqrt{\frac{1 - c}{2}} \\ \mathbf{q}_k &= n_z \sin\frac{\theta}{2} = n_z \sqrt{\frac{1 - c}{2}} \\ \end{aligned} \right.$$ As you see, all you need to remember is to normalize the cross product (rotation axis $\vec{n}$) by dividing it by its 2-norm, $\lVert\vec{n}\rVert = \sqrt{\vec{n}\cdot\vec{n}} = \sqrt{n_x^2 + n_y^2 + n_z^2}$), and to halve the rotation angle; I included the two half-angle formulas in the first set for $0 \le \theta \le 180°$.

Also note that the result indeed is an unit quaternion, $\lVert\mathbf{q}\rVert = \sqrt{q_r^2 + q_i^2 + q_j^2 + q_k^2} = 1$. (If weren't isn't, you can always normalize it safely, without introducing any directional bias, by dividing it by its length (that square root). The $q_r = 1$, $q_i = q_j = q_k = 0$ represents no rotation, in case the division yields a non-finite value.)

  • 1
    It is not necessary to use the cross product as the axis. Think any two vectors ending on the surface of the unit sphere, on the same latitude (with respect to some system of spherical coordinates). You can then simply rotate about the axis connecting the poles of that sphere. In fact, there are infinitely many different rotations taking a given vector to another. – Jyrki Lahtonen Sep 01 '22 at 15:13
  • 1
    @JyrkiLahtonen: Nevertheless, the cross product will yield the axis that provides the extremum rotations, i.e. the great circle that passes through both vectors on the unit sphere. The above method will always yield the minimum rotation (smallest rotation angle possible). To get the maximum rotation, negate either $\mathbf{q}_r$, or the other three components. – Blabbo the Verbose Sep 01 '22 at 16:30
  • 1
    True. It is a natural choice. – Jyrki Lahtonen Sep 01 '22 at 17:07
1

Let the angle between $a$ and $b$ be $\theta$. Now, there's a formula for the quaternion multiplication that relates it to the cross product and cosine and sine of $\theta$. Note that throughout I'm using the usual representation of $a,b$ and $b\times a$ and $a\times b$ as quaternions with real part zero. (They have the same coefficients as their vector counterparts in front of $i,j,k$.)

The identity I speak of is $$ba=-\cos(\theta)+\sin(\theta)(b\times a)$$

But if we rewrite this,

$$-\cos(\theta)+\sin(\theta)(b\times a)=\\ -\cos(\theta)-\sin(\theta)(a\times b)=\\ -(\cos(\theta)+\sin(\theta)(a\times b)) $$

We recognize this quaternion is precisely (up to a negative sign, which doesn't matter of course!) the rotation around $a\times b$, but unfortunately the angle is two times what we need! So we want this to all wind up with the angle being half of what it is.

What we need is a unit vector bisecting the angle between $a$ and $b$ so that we can obtain the same thing with $\theta/2$, and luckily the answer is geometrically obvious:

$$c=\frac{a+b}{\|a+b\|}$$

Since $q=ca=-(\cos(\theta/2)+\sin(\theta/2)(a\times b))$ it will do exactly what you want: rotate $a$ onto $b$ by rotating the plane $a$ and $b$ span. (So there is no mistake, I refer to $x\mapsto qxq^{-1}$)

To reiterate, the formula is:

$$q=\frac{(a+b)a}{\|a+b\|}$$

There are corner cases, of course, when $a$ and $b$ are linearly independent but I gather you are restricting yourself to a valid case.

rschwieb
  • 160,592