This site uses strictly necessary cookies. More Information

X- Home /

# Rotate vector around vector?

I have two perpendicular vectors - v1 and v2. How to rotate v1 around v2 with a given angle?

**Answer** by JVene
·
Jul 14, 2018 at 07:02 AM

@David_Simoniants, I must admit this is the close of my day at 3am, and I'll try to visit sometime on Saturday to clean this up with a test, so I'm not testing this tonight, but here's the plan:

Fundamentally this is about performing a rotation in a local coordinate system, then transforming that into the global coordinate system (or at least the parent of this one).

Two perpendicular vectors conveniently form their own local coordinate system. The green perpendicular indicator between the two black vectors depicted define the local axes of what I assume to be X and Y coordinates. If these are both normalized vectors, the length of both is 1. In their local coordinate systems, under that condition, one vector has an x of 0 and a y of 1, while the other has a y of 0 and an x of 1. However, if they're not normalized, then the first of the two black vectors (the one pointing up, which we choose arbitrarily and is somewhat obvious by your diagram) will have an x coordinate of zero, but it's y is the vector's length. Likewise, the other vector has an x coordinate of it's length, and a y of zero. This second vector is what you're rotating to the red vector.

The rotation to the red vector is, therefore, a rotation in the local XZ plane, which can be determined by typical rotation of a point, as in (where vs is the source vector in local coordinates, it's x is the vectors length, and v1 will be the **local** coordinate result)

```
v1.x = cos(a) * vs.x - sin(a) * vs.y;
v1.z = sin(a) * vs.x + cos(a) * vs.y;
```

Yet, the y of the source black vector is zero in the local coordinate system (x is the vector's length), so this can be simplified in code to

```
v1.x = cos(a) * vs.x;
v1.z = sin(a) * vs.x;
```

At this point you have v1 in the **local** xz plane, but you need that to be transformed into the coordinate system implied by the attitude of either source vector. In the local coordinate system the source vectors imply, both would be on either the X axis or the Y axis. The source for v1 is the one on the x axis, and it's convenient enough to use, but this would work from either of the source vectors because they are defined as perpendiculars in their local coordinate system.

This means that the source vector's global positions for it's own coordinates can be used to define the Euler angles of each pertinent plane, from which you could fashion a quaternion via arctan2, and use that to rotate the v1 calculated above (which is in the local coordinate system) into the global coordinate system (your goal).

If the source vectors are normalized, such that their lengths are 1, you're in luck. You're not entirely out of luck if they aren't, it's just a little more work.

Think of this perpendicular pair as being rotated from an aligned coordinate system (their local), such that both started out on the X and Y axis, but have been rotated into their now global coordinate attitude. Since they are unit vectors, they imply tangents relative to the rotation described. That is, in the global xy plane, their coordinates show the tangent which describes their angle in the xy plane. You can use Mathf.Arctan2( y, x) to find that angle (in radians).

Mathf.Arctan2( y, x ) puts the y coordinate first (other libraries put x first, and this seems odd, but it's related to the fact that tangent is y/x, whereas arctangent is the angle of that tangent. To convert the return value into degrees (required for Quaternion.Euler), multiply by Mathf.Rad2Deg.

Mathf.Arctan2( y, x) provides the angle on the Z axis, the 3rd parameter required for Quaternion.Euler( x, y, z ). You'll need to use Mathf.Arctan2 for each axis, selecting xz coordinates for the y axis, etc.

If, however, these are not normalized vectors, so they are not unit vectors, what you require is the deflection of the coordinates. Say the source vector from which you obtained v1 (the one that's on the X axis in it's local coordinate system) is length 5. The x coordinate for that vector in it's local coordinate system is 5, it's y is zero. Now, let's say that in the **global** coordinate system the x coordinate of that vector is 4.5. It's attitude is such that x was moved from 5 to 4.5. It's length is 5, and so if this **were** a unit vector, a length of 1, it would have moved from 1 to ( 4.5 / 5 ), or 0.9. You can now use 0.9 as if this were a normalized vector to continue with Mathf.Arctan2( y, x ). Of course, it is likely that in the global coordinate system, y is no longer zero, and you'll need to perform the same calculation for y.

Again, doing so for each axis from which to form a quaternion, which you then use to rotate the v1 calculated above with

```
v1 = q * v1;
```

Where q is the quaternion you fashion.

I'm glad that worked, but I now see I made two errors, one minor.

The minor one: you don't have to correct for non-unit vectors. Tangent is a ratio, so the scaling (4.5/9 = 0.9) doesn't actually do anything. It doesn't corrupt the result, but it isn't required.

The other error is a lack of clarification on my part. I didn't make it clear you need only 2 axis when creating the quaternion (in fact, a 3rd axis would corrupt the result slightly). Choose any 2 axis and leave the other parameter for Quaternion.Euler at zero.

*Sorry if I made mistakes in my English!*

Your answer is large and full of info (thank you for that) but I simplified it. I calculated v1 in local space and transformed it into global space by quaternion and probably your errors didn't cause me any problems. Thanks again.))

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Rotating a character's velocity? 3 Answers

How can I calculate the Vector3 b using Vector 3 a pos with an angle? 1 Answer

rotate player on y axis or Vector.up regradless of orientation 0 Answers

Raycasting at an offset angle? 4 Answers

Arbitrary rotation around a point works except when up flips? 1 Answer