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?
How to rotate vector to face more in the direction of another vector?
757 Views Asked by Bumbble Comm https://math.techqa.club/user/bumbble-comm/detail AtThere are 2 best solutions below
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)$$
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) $