How to rotate vector to face more in the direction of another vector?

757 Views Asked by At

I have 2 vectors, lets say vector $a$ and vector $b$. I want to rotate vector $a$ to face more in the direction of vector $b$, but I want to have some maximum angle of the rotation. For example, if $a$ would be $(0, 0, 1)$, $b$ would be $(0, 1, 0)$ and the maximum angle 45°, I want to output $(0,\sqrt{0.5},\sqrt{0.5})$. I can do it in 2D, but I need it in 3D and there I have a problem with limiting the rotation to the angle. Is this possible in some way, that isn't much processing-heavy?

2

There are 2 best solutions below

12
On BEST ANSWER

Define the unit vectors along $a$ and $b$ as $u_1 = \dfrac{a}{|a|} $ and $u_2 = \dfrac{b}{|b|} $.

First compute the angle between $a,b$ as $\phi = \cos^{-1} u_1 \cdot u_2 $

Then after rotating vector $a$ , the final angle between $a$ and $b$ is given by

$\psi = \max \{ 0, \phi - \theta_\text{MAX} \} $

This way, if $\theta_\text{MAX} $ is greater than $\phi $ then $\psi $ will be zero.

Now we need to express the final rotated vector $a'$ in terms of $u_1$ and $u_2$

A unit vector lying in the plane of $u_1$ and $u_2$ and perpendicular to $u_2$ is given by

$ u_3 = \left( \dfrac{u_2 \times u_1}{|u_2 \times u_1|} \right) \times u_2 $

Where $\times$ denotes cross product. Finally, the rotated vector $a'$ is

$ a' =|a| \left( (\cos \psi) u_2 + (\sin \psi) u_3 \right) $

3
On

My answer will work for any (finite) number of dimensions, including 3.

We have our goal direction vector, $\mathbf{b}$, and a starting vector $\mathbf{a}$. We will assume $\mathbf{a}$ and $\mathbf{b}$ are not parallel (since no rotation of $\mathbf{a}$ would be needed), nor antiparallel (since it would be impossible to choose a unique direction of rotation).

Then the 2D plane containing both vectors is given by $\text{Span}\{\mathbf{a},\mathbf{b}\}$ and can be parametrized using unit direction vectors:

$$\text{Span}\{\mathbf{a},\mathbf{b}\} = \bigg\{ s\Big(\frac{\mathbf{a}}{|\mathbf{a}|}\Big) + t \Big(\frac{\mathbf{b}}{|\mathbf{b}|} \Big) \large\;\mid\; \normalsize s, t \in \mathbb{R} \bigg\}$$

Let's now denote the general point on the plane as $\big[s, t\big]$. Therefore, the starting vector is $\mathbf{a}=\big[ |\mathbf{a}|, 0 \big]$ and the "goal" vector is $\mathbf{b}=\big[ 0, |\mathbf{b}| \big]$

A rotation of $\mathbf{a}$ "towards" the goal vector $\mathbf{b}$ should also lie on this plane. It would look like

$$\text{ROT}_\mathbf{a}^\mathbf{b}(\phi)=\big[ |\mathbf{a}|\cos \phi, |\mathbf{a}|\sin\phi\big]$$

where $\phi \in \big[0, \frac{\pi}{2}\big]$. Caution: the parameter $\phi$ does NOT refer to the angle of rotation, since the original vectors $\mathbf{a}$ and $\mathbf{b}$ are not necessarily orthogonal to each other! The important properties are:

  • $\big|\text{ROT}_\mathbf{a}^\mathbf{b}(\phi)\big|=|\mathbf{a}|$ for all $\phi$;
  • $\text{ROT}_\mathbf{a}^\mathbf{b}(0)=\mathbf{a}$; and
  • $\text{ROT}_\mathbf{a}^\mathbf{b}\big(\frac{\pi}{2}\big) \parallel \mathbf{b}$.

The last step is to figure out how to convert a given angle of rotation $\theta$ to a corresponding value of the rotation parameter $\phi$. This is why we used unit vectors in our definition of the Span: it makes the angle-conversion much easier... no weird elliptical stretching!

The total angle between $\mathbf{a}$ and $\mathbf{b}$ is given by $\theta_\text{max}=\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)$. We can compare the domains for the rotation parameter $\phi$ and the rotation angle $\theta$ to write the equation converting between them:

$$\phi \in \big[ 0 , \frac{\pi}{2} \big]$$ $$\theta \in \big[0 , \theta_\text{max} \big]$$ $$\phi = \frac{\pi}{2\theta_\text{max}}\cdot \theta$$

Therefore, to rotate by a given angle $\theta$, we will use:

$$\text{ROT}_\mathbf{a}^\mathbf{b}\Big(\frac{\pi\theta}{2\theta_\text{max}}\Big)=\text{ROT}_\mathbf{a}^\mathbf{b}\Big(\frac{\pi\theta}{2\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)}\Big)$$ $$=\bigg[ |\mathbf{a}|\cos \Big(\frac{\pi\theta}{2\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)}\Big) \, , \; |\mathbf{a}|\sin\Big(\frac{\pi\theta}{2\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)}\Big)\bigg]$$

$$=\mathbf{a}\cdot\cos \bigg(\frac{\pi\theta}{2\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)}\bigg) + \mathbf{b} \cdot \frac{|\mathbf{a}|}{|\mathbf{b}|}\sin\bigg(\frac{\pi\theta}{2\arccos \big( \frac{\mathbf{a}\cdot \mathbf{b}}{|\mathbf{a}| |\mathbf{b}|} \big)}\bigg)$$