I think this question is pretty basic to someone who has knowledge about vector operations. I am developing a game and I have ran into a problem where I have the following vectors. For simple understanding I made a colored explanation:

Vector problem The purple vector is based on user input (so I will always know it). The blue vector is just pointing up (this is just for explanation). I also have the green vector which is fixed in length but is based on the player's rotation which can be anything, this is basically forward direction for my player.

What I am planning to do is to create the red vector which should be the same length as the purple one. Also, the red vector's angle should differ by the same angle from the green vector as the purple vector differs from the blue one. I believe this is called theta (sorry if I am incorrect I only learnt vectors in high school :) )

So my main question is: what kind of transformation should I do to get the red vector from the other 3 input vectors?

My idea is to multiply the blue vector with the purple (Purple xGreen x,Purple yGreen y) but I have no idea about the angle "transformation". (I have even watched youtube for like two hours now, but this seems to be not a basic operation)

Thank you in advance for your kind help! David

P.s.: If you can give me hints about places where I can learn more about this topic I would be happy as well, because I think I will need this kind of knowledge in the future too.


No need for trig, poorly conditioned calcs of $θ$, or matrices

You did correctly intuit that you need the "right" Vector Product(s)

the Vector Algebra taught in High School, early Undergrad today is Gibbs Vector Algebra which, though stuck in 3D, can be used for 2D calcs like this although some may never see or use the Vector Triple Product used in the below expression for rotating the Green vector to create the Red output vector
To use the Gibbs 3D Cross Product with the 2D vectors of the problem, the 2D vectors can be temporarily "promoted" to 3D vectors by augmenting each with a $z = 0$ component
then the Gibbs Vector Algebra formula for rotating g (3D vector derived from the 2D Green) by the angle between p, b (3D vectors derived from the 2D Purple, Blue, resp.) is:

$\left(\left(p\cdot b\right)g+(p\times b)\times g\right)/\begin{vmatrix}p\end{vmatrix}$

For coding the operation you may want to go down to the Vector Component level depending on your programing language, environment choices

1st a little help from GeoGebra's Computer Algebra System with the Triple Cross Product term: enter image description here

Still requires hand massaging (as is typical of CAS output) but shows the simplifications with the $z$ components zero in all of the input and output vectors
Adding in by hand the Dot Product term and the Normalization, the final by component rendering isn't that daunting:

(dropping the temporary z component to get a 2D output)

$(r_{x},\;r_{y}) =$ $\left[\left(p_{x}b_{x}+p_{y}b_{y}\right)g_{x}+(b_{x}p_{y}-b_{y}p_{x})g_{y},\;\left(p_{x}b_{x}+p_{y}b_{y}\right)g_{y}+(b_{y}p_{x}-b_{x}p_{y})g_{x}\right]/\sqrt{p_{x}^{2}+p_{y}^{2}}$

The equations could still have typos but the method is verified in a "live" dynamic geometry GeoGebra worksheet I uploaded to Geogebra:

pic below is static, the Geogebra link should get you to the live worksheet where the spherical points at the heads of of the input vectors can be dragged with the result updating dynamically (although I did the full normalization of the Rotor there so the output magnitude is independent of both Purple, Blue magnitudes, only tracks Green)

The pink z axis vector is the $(p\times b)$ term, which, together with $\left(p\cdot b\right)$ are the components of a 2D Rotor expressed in Gibbs 3D Vector Algebra
The Rotor is a good object to encode the rotation with, particularly with the input given as a pair of vectors $p, b$
If you want to reverse the sense of the output angle rotation relative to the input vector pair ording, just change the sign in front of the $(p\times b)$ term

The Rotor equation is simpler in Geometric Algebra which I highly recommend even though the final calculation from components ends up the same
The wedge product of Geometric Algebra works in any dimension so the "promotion/demotion" step to use the Gibbs 3D Cross Product isn't required in GA, everything can stay in 2D

There are now many online (and dead tree) Geometric Algebra resources: Geometric Algebra for Computer Graphics may be especially relevant to this question

  • $\begingroup$ Thank you! This was the solution I finally implemented. As you also proposed I changed the plus to a minus in front of the (p x b) term. However it works perfectly now! $\endgroup$ – Phonebox Nov 5 '16 at 10:20

We need to compute the angle between the blue and the green vector, let's call it $\theta$. We can do this with the properties of the dot product, i.e.,

$$\cos(\theta)=\frac{\text{Blue}_x \text{Green}_x+\text{Blue}_y\text{Green}_y}{\text{length(Blue)length(Green)}}$$

from which we may compute the angle $\theta$. Then we can simply multiply the Purple vector $$\begin{bmatrix} \text{Purple}_x & \text{Purple}_y\end{bmatrix}$$ by the rotational matrix $$\begin{bmatrix}\cos(\theta) & \sin(\theta)\\-\sin(\theta) & \cos(\theta)\end{bmatrix}$$ (using -$\theta$ from the formula found here to obtain a clockwise rotation) to get $$\begin{bmatrix} \text{Red}_x & \text{Red}_y\end{bmatrix}$$

Please let me know if there's anything confusing about that!

  • $\begingroup$ also relevant and kind of funny once you understand the rotation matrix: xkcd.com/184 $\endgroup$ – Giuseppe Nov 3 '16 at 20:45
  • 1
    $\begingroup$ There’s no need to compute the angle itself. Once you have $\cos\theta$, you can construct the rotation directly. $\endgroup$ – amd Nov 4 '16 at 5:09
  • $\begingroup$ Dear Giuseppe! Thank you so much for the detailed answer! I will create the code based on this tonight and let you know if it works properly. Also, this is a great explanation for me. $\endgroup$ – Phonebox Nov 4 '16 at 6:15
  • $\begingroup$ deriving the angle from the dot product is poorly conditioned, more robust is also using the information in the cross product, ie both sin and cos together $\endgroup$ – f5r5e5d Nov 4 '16 at 8:02

You don’t say how the green vector is derived. Presumably, somewhere along the way you have an angle $\theta$ the gives the player’s rotation. As you say, the red vector can be derived from the purple via a rotation transformation. If you have a right-handed Cartesian coordinate system, the usual convention is for positive angles to represent counterclockwise rotations. With that convention, the rotated version of a vector $(x,y)$ is given by $$\begin{align}x'&=x\cos\theta-y\sin\theta \\ y'&=x\sin\theta+y\cos\theta, \end{align}$$ or, in matrix form, $$\begin{bmatrix}x'\\y'\end{bmatrix}\begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}.$$ (If a positive angle instead represents a clockwise rotation, change the sign of the $\sin\theta$ terms.)

If you don’t have the angle $\theta$ between the blue and green vectors (call them $\mathbf b$ and $\mathbf g$) handy, you can recover it from them via the dot product: $$\mathbf b\cdot\mathbf g = \|\mathbf b\|\,\|\mathbf g\|\cos\theta$$ and so $$\cos\theta={\mathbf b\cdot\mathbf g\over\|\mathbf b\|\,\|\mathbf g\|}.$$ You don’t have to compute the angle $\theta$ itself to derive the rotation. Once you have $\cos\theta$, you can get $\sin\theta$ via the identity $\cos^2\theta+\sin^2\theta=1$, though you have to take a bit of care to get the sign right.

In your situation we can simplify things a bit. Assuming that “up” corresponds to the positive $y$-direction, $\mathbf b\cdot\mathbf g=(0,y_b)\cdot(x_g,y_g)=y_by_g$, but $\|\mathbf b\|=y_b=\|\mathbf g\|$, so $$\cos\theta={y_g\over y_b}={y_g\over\sqrt{x_g^2+y_g^2}}$$ and with a bit of thought you should be able to convince yourself that $$\sin\theta=-{x_g\over y_b}=-{x_g\over\sqrt{x_g^2+y_g^2}}.$$ The rotation matrix is therefore $$R=\frac1{\sqrt{x_g^2+y_g^2}}\begin{bmatrix}y_g&x_g\\-x_g&y_g\end{bmatrix}$$ which represents the transformation $$\begin{align}x'&={y_gx+x_gy\over\sqrt{x_g^2+y_g^2}}\\y'&={-x_gx+y_gy\over\sqrt{x_g^2+y_g^2}}.\end{align}$$ Of course, if $\mathbf b$ and $\mathbf g$ are unit vectors, this becomes even simpler since there’s no need to normalize.

Note that we could’ve instead derived this matrix directly from the vector $\mathbf g$ by taking advantage of the fact that the columns of a transformation matrix are the images of the basis vectors. Again, assuming that “up” is the positive $y$-direction, the rotation maps $(0,1)$ onto $\mathbf g/\|\mathbf g\|$ (i.e., $\mathbf g$ normalized), which is the second column of $R$. It also maps $(1,0)$ onto a vector 90 degrees clockwise from $\mathbf g/\|\mathbf g\|$. For any vector $(x,y)$, rotating it 90 degrees clockwise yields $(y,-x)$, which you can verify is the first column of $R$.

  • $\begingroup$ Okay thank you amd for your answer! I answer your assumptions: 1. The green vector and the blue vector are both the same 1 unit length as you assume. I have both of them when I start the calculation yes. The only one which differs in length at the start is the purple vector, and that should be the length of the green vector. 2. I do not have θ at the start (only if I make your proposed calc.) 3. Yes, the up means (0,1) as you are assuming. $\endgroup$ – Phonebox Nov 4 '16 at 6:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.