Rotate into a vector direction

linear-transformationsprogrammingrotationsvector analysis

I have a vector $$start-end = u \in \mathbb{R^{3}} $$
and a Rotationmatrix which takes three angles as arguments and rotates like:
$$ M_{rot} = M_{Z} M_{Y}M_{X}$$

How can i calculate the angles, which rotate u in my z-direction that start is headed into the viewing direction, e.g in -z?
The Problem with using the asin function for the angle between the coordinate surfaces and my vector gives me numerical errors in the rotation, and the angles are dependent from where start and end are located.

The rotation is only to take place in octant 0.

I think it is not hard to solve, but at the moment im drawing a blank, so i would appreciate your help 🙂

enter image description here

Best Answer

What I understand is that the rotation should rotate the vector $u$ to a vector $u'$ pointing in the direction of the positive $z$ axis.

In the usual interpretation of what a vector is in $\mathbb R^3,$ the vector $u$ does not actually have a particular start or end point; it merely gives a direction and distance; but you can perfectly well specify the vector $u$ by specifying two points, $\newcommand{\startp}{\mathit{start}\,}\startp$ and $\newcommand{\endp}{\mathit{end}\,}\endp$, and taking the differences in those points' coordinates to get the coordinates of $u.$ Moreover, once you have a rotation that makes the image $u'$ point in the positive $z$ direction, the same rotation will take $\startp$ to a point $\startp'$ and take $\endp$ to a point $\endp'$ such that if you name the $x,y,z$ coordinates of these points by using the subscripts $x,y,z$ then \begin{align} \endp_x' &= \startp_x', \\ \endp_y' &= \startp_y', \\ \endp_z' &= \startp_z' + \lVert u\rVert > \startp_z'. \\ \end{align} This seems to match your sketch.

Assuming that rotation matrices are applied on the left side of a vector (the usual convention), the function that you have chosen to use, $$ M_{\mathit{rot}} = M_{Z} M_{Y}M_{X},$$ performs the $Z$ rotation last. This rotation preserves the angles that vectors make with the $z$ axis, so if we are to get $u'$ parallel to the $z$ axis we are not going to do it with this last step; we must do it with the rotations around the $x$ and $y$ axes instead.

The rotation around the $y$ axis will not be able to "correct" any difference in the $y$ coordinates of the start and end points, so we need the first rotation, the one around the $x$ axis, to rotate the points to the same $y$ coordinate. We do this by rotating $u$ to a vector parallel to the $x,z$ plane; that is, eliminate its $y$ coordinate.

You can consider a rotation around the $x$ axis to leave all $x$ coordinates unchanged but to rotate the projections of points on the $y,z$ plane. The projection of $u$ on the $y,z$ plane is $(u_y, u_z)$; we want to rotate this projected vector to the vector $\left(0, \sqrt{u_y^2 + u_z^2}\right),$ which has the same length but whose direction is the positive $z$ direction.

You can find the angle that the vector $(u_y, u_z)$ makes with the $z$ axis in the $y,z$ plane using the formula $$ \alpha = \newcommand{\atan}{\mathrm{atan2}} \atan(u_y, u_z). $$

I am assuming here that you have the usual implementation of $\atan,$ in which $\atan(y,x)$ gives you the angle of the vector $(x,y)$ in the $x,y$ plane measured in the counterclockwise direction from the $x$ axis. But because we are doing $\atan(u_y, u_z)$ instead of $\atan(u_y, u_x),$ if you have the usual right-handed set of $x,y,z$ axes, and if you are looking onto the $y,z$ plane from the positive $x$ axis, the angle $\alpha$ is measured in a clockwise direction starting from the positive $z$ axis.

Note that the range of output of the $\atan$ function in most software implementations is either $[-\pi,\pi)$ or $(-pi,\pi].$ If $u_y > 0$ this will result in a positive angle; if $u_y < 0$ it will result in a negative angle. If $u_z > 0$ the magnitude of the angle will be less than $\pi/2,$ but if $u_x < 0$ the magnitude of the angle will be greater than $\pi/2.$ In short, no matter which way your original vector is pointing, $\atan(u_y, u_z)$ will tell you exactly how much it is rotated away from the positive $z$ direction (even if that is an obtuse angle) and in which direction, and it will identify exactly which of the four quadrants in the $y,z$ plane the vector points toward. This makes $\atan$ much more convenient than function such as $\mathrm{asin}$ or even the one-parameter $\mathrm{atan}$ function, which can only give you angles in two quadrants and therfore (in general) give you the wrong direction whenever the correct direction was in one of the other two quadrants.

If the $M_X$ parameter of your rotation function represents the conventional right-handed rotation around the $x$ axis, then $\alpha$ is exactly the rotation angle you need in order to rotate $u$ parallel to the $x,z$ plane. But you can set up a test case with an arbitrary $u$ (for example $u = (1,2,3)$) and try both rotation directions ($\alpha$ and $-\alpha$) to see which one zeros out the $y$ coordinate of the result in your software.

The result of this first rotation, viewed as a vector parallel to the $x,z$ plane, has coordinates $\left(u_x, \sqrt{u_y^2 + u_z^2}\right).$ So it makes an angle $$ \beta = \atan\left(u_x, \sqrt{u_y^2 + u_z^2} \right) $$ with the positive $z$ axis. If you are looking at the $x,z$ plane from the positive $y$ axis, the angle $\beta$ is measured counterclockwise from the positive $z$ axis, so the necessary rotation around the $y$ axis to bring the vector parallel to the $z$ axis is $-\beta$; but you can try both $-\beta$ and $\beta$ with a test vector in your software to find out which one is correct.

So the sequence of axis rotations, depending on exactly how your software interprets the axes and rotation angles, is:

$\alpha$ (or possibly $-\alpha$) around the $x$ axis;

$-\beta$ (or possibly $\beta$) around the $y$ axis.

You can then do any rotation you like (or a zero rotation) around the $z$ axis without any effect on the correctness of the result; but rotation around the $z$ axis will move both the $\startp'$ and $\endp'$ points to any direction from the $z$ axis you want. (That is, you can't change the $z$ coordinates, but you can take the $x$ and $y$ coordinates anywhere along a circle around the $z$ axis.)