• 13
• 18
• 19
• 27
• 10

# how to get the "oriented" angle between two vectors

This topic is 3685 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I am working on an OpenGL simulation of a physical process. An 3D rigid object moves in the world system, so at any point in time I have what I think is known as the orientation matrix, i.e. the matrix in which the rows are the unit vectors that define the object's local system axes in the world system. I need to compute the electric field of a charge fixed in world system at various points in the 3D object. I know these points as vectors in the local system. Thus, I need to translate/rotate them to the world system to do the calculation. A priori, it would seem relatively simple to get the Euler angles from the orientation matrix, but any method I can think of for my program uses dot or cross product and would give me the smallest angle between two vectors, not the oriented angle (i.e. following the right-hand rule) which is the one I need for the rotation matrix. I hope I am not being confusing in what I need. As an example, say my local system and the world system have the same z orientation, and the x axis of the local system points as world (1,-1,0). Thus, the Euler angle phi is 315, or -45, but the dot product between the two x-axes would give me 45. Of course I can check the signs of the x/y components to determine the angle correctly, but this gets very involved (at least for me) in a general orientation case, in which the three Euler angles are non-zero. What do you guys do in these cases? How does one compute the "true", oriented angle between two vectors (i.e. from vector A to vector B, say) in a practical way in a program? Conversely, do you know of another way other than the Euler angles way for a rotation that is more proper in programming? (I am a physicist, not a programmer) Thank you very much for any help, mc61

##### Share on other sites
You don't need to use angles at all. Just compute the mapping from local coordinates to global ones. This mapping is an affine transformation, whose matrix can be built from the orientation matrix and the translation vector (the difference between the origins of the two reference frames).

If you need more details, maybe you can post an example and I can do the numbers on your example.

##### Share on other sites
Dear Alvaro,

Wow, that sounds quite promising. I am familiar with what an affine transformation is in general, but I do not know how to build one in this case. Thus, if you could give me the details on how to build it, that would save my life. Would it be too much to ask to have it built without specific numbers, so I can learn?

If so, let's say that at one point in the simulation the three unit vectors that fix the local system are Sx, with coordinates (Sx1, Sx2, Sx3) in the world system; Sy with coordinates (Sy1, Sy2, Sy3); and Sz with coordinates (Sz1, Sz2, Sz3). Thus, if I am not mistaken, what game programmers call the orientation matrix is

[Sx1 Sx2 Sx3]
[Sy1 Sy2 Sy3]
[Sz1 Sz2 Sz3]

The world origin is (0,0,0) and the local system origin is at vector R, with coordinates (r1, r2, r3). Say a vector of interest in the local system is A = (a1, a2, a3).

I truly, really, definitely appreciate your help :-)

mc61

##### Share on other sites
Given your example, the mapping from local coordinates to world coordinates is:
world_coord = local_coord * orientation_matrix + translation
You can simplify this by combining the orientation and translation into a single homogeneous 4x4 matrix transform. Then you have:
world_coord = local_coord * transform_matrixlocal_coord = world_coord * inverse(transform_matrix)
In this case, your coordinates will need to be expressed as 4-d vectors with the w component set to 1 (unless you have specialized 'transform point/vector' functions available, in which case you may be able to work directly with 3-element vectors).

##### Share on other sites
Thank you!

I have to try this one and think about it, as I do not understand yet why it works :-).