Jump to content

  • Log In with Google      Sign In   
  • Create Account

How do I rotate a 2D Vector?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Chris_Devl   Members   -  Reputation: 101

Like
0Likes
Like

Posted 17 June 2014 - 07:15 PM

I've posted this general programming question on other forums, but haven't had much luck. Hopefully someone here can help me.

 

As the title says, I have a 2D unit vector, and I simply need to rotate it by X degrees. I've done a lot of googling, and couldn't really find what I needed (most similar problems I found were quite a bit more complex).

Also I'd be calling this up to 4 times per update, so I'm hoping for a solution that isn't horrible on performance.

 

Tried multiplying my vector like the following as suggested online:

Quaternion.AngleAxis(Camera.main.transform.rotation.y, Vector3.forward) * new Vector2(Input.GetAxis("P1MoveHorizontal"), Input.GetAxis("P1MoveVertical"))

Input.GetAxis returns a float from -1 to 1 representing the X position of the joystick. (So the joystick direction is a unit vector).

Didn't make any difference.
And
 

    Quaternion.AngleAxis(Camera.main.transform.rotation.y, Vector3.forward) * new Vector2(Input.GetAxis("P1MoveHorizontal"), Input.GetAxis("P1MoveVertical"))

Gives me an error where Quaternion cannot multiply with a vector2.


Tried this:
 

    float sin = Mathf.Sin(Camera.main.transform.rotation.y);
            float cos = Mathf.Cos(Camera.main.transform.rotation.y);
    
            float tx = Input.GetAxis("P1MoveHorizontal");
            float ty = Input.GetAxis("P1MoveVertical");
            Move(new Vector2((cos * tx) - (sin * ty), (cos * ty) + (sin * tx)));

Made a difference, but still not the correct directions.

I even tried convert the unit vector to degrees, adding the camera's rotation in degrees, and then converting it back into a vector:
 

    float directionAngle = Mathf.Atan2(Input.GetAxis("P1MoveVertical"), Input.GetAxis("P1MoveHorizontal"));
            directionAngle += Camera.main.transform.rotation.y;
            Move(new Vector2(Mathf.Sin(directionAngle), Mathf.Cos(directionAngle)));

But EVEN THIS which I was certain would work but was hoping to avoid for inefficiency, is not working at all as expected. Without even inputting a direction my object moves around in circles and wanders off the scene.
 



Sponsor:

#2 Samith   Members   -  Reputation: 2256

Like
3Likes
Like

Posted 17 June 2014 - 07:53 PM

 Let v be your vector and R be the rotation matrix. Simply multiply v by R to get the rotated vector.

v = [ x y ]
R = [ cos(theta) -sin(theta)
      sin(theta)  cos(theta)]

Rotated_v = R * transpose(v)
          = [ cos(theta) * v.x - sin(theta) * v.y
              sin(theta) * v.x + cos(theta) * v.y ]

This looks similar to one of your attempts, the one where you said you didn't get "the correct directions". What did you mean by that? Did it rotate in the opposite direction that you thought it would? 

 

EDIT: For some justification: the columns of R are the basis vectors of the identity matrix under a rotation of theta degrees. Rotation is a linear operation that transforms a vector into a rotated space, which is what the R matrix represents (the identity rotated by theta degrees).

 

EDIT2: I'm not exactly sure what Camera.main.transform.rotation.y contains. What type is camera.main.transform.rotation? I'm going to guess that it's a quaternion storing the orientation of your camera. In that case, rotating by the y component of the quaternion that represents your camera's orientation doesn't make much (any) sense. You'll have to provide a bit more information for us to understand what exactly you're trying to accomplish here.


Edited by Samith, 17 June 2014 - 08:03 PM.


#3 Chris_Devl   Members   -  Reputation: 101

Like
0Likes
Like

Posted 18 June 2014 - 10:44 AM

 Let v be your vector and R be the rotation matrix. Simply multiply v by R to get the rotated vector.

v = [ x y ]
R = [ cos(theta) -sin(theta)
      sin(theta)  cos(theta)]

Rotated_v = R * transpose(v)
          = [ cos(theta) * v.x - sin(theta) * v.y
              sin(theta) * v.x + cos(theta) * v.y ]

This looks similar to one of your attempts, the one where you said you didn't get "the correct directions". What did you mean by that? Did it rotate in the opposite direction that you thought it would? 

 

EDIT: For some justification: the columns of R are the basis vectors of the identity matrix under a rotation of theta degrees. Rotation is a linear operation that transforms a vector into a rotated space, which is what the R matrix represents (the identity rotated by theta degrees).

 

EDIT2: I'm not exactly sure what Camera.main.transform.rotation.y contains. What type is camera.main.transform.rotation? I'm going to guess that it's a quaternion storing the orientation of your camera. In that case, rotating by the y component of the quaternion that represents your camera's orientation doesn't make much (any) sense. You'll have to provide a bit more information for us to understand what exactly you're trying to accomplish here.

 

Yeah you guessed correctly. Camera.main.transform.rotation.y wasn't what I thought it was, now I'm using Camera.main.transform.rotation.eulerAngles.y instead. It still doesn't work properly. The directions DO change (incorrectly), and I can't find a pattern with it really.. It's just the more rotated the camera is from it's original position, the less accurate the direction offset seems to be. In one direction the controls get reversed, in another all controls are 90 degrees off.

 

I'm not sure how to use matrices in code.. Honestly I didn't think I'd need matrices for something so simple anyway.

 

EDIT: OH and apparently sin and cos take their arguments in radians, which confused me a bit as I remember always putting in degrees in school, but either way now I have the angle converted to radians and still have the problem mentioned above.

 

EDIT: Solved. Apparently Sin functions aren't consistent in what sign they return their result in. I tried switching it to -sin and all works fine. Thanks for the help!


Edited by Chris_Devl, 18 June 2014 - 11:07 AM.


#4 DiegoSLTS   Members   -  Reputation: 1350

Like
3Likes
Like

Posted 18 June 2014 - 11:36 AM


EDIT: Solved. Apparently Sin functions aren't consistent in what sign they return their result in. I tried switching it to -sin and all works fine. Thanks for the help!

A basic math function is wrong? If that's the case a lot of people should have complained about it a long time ago. Are you sure it's a problem with the function?

 

Maybe the angle you're sending is wrong... -sin(a) == sin(-a) and cos(a) == cos(-a) so you'll get the right value for cos but the other value for sin if you have the wrong sign on the angle. Changing the angle instead of the sin result seems like a better idea to me.


Edited by DiegoSLTS, 18 June 2014 - 11:37 AM.


#5 CowKing   Members   -  Reputation: 152

Like
0Likes
Like

Posted 19 June 2014 - 10:37 PM

I assume you're using Unity3D, and you're in "2D" mode. In which case, you need to use unity's depth axis 'Z'. You need to rotate the object on it's Z axis. I got really confused on that as well.

 

Here's what I used to rotate a point:

theta is in radians

private static Vector2 Rotate2DPoint(Vector2 point, float theta) {
		float sinT = Mathf.Sin(theta); float cosT = Mathf.Cos(theta);
		return new Vector2(
			point.x*cosT - point.y*sinT,
			point.x*sinT + point.y*cosT
			);
}





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS