Okay, I give up. I've scoured the internet and my texts. And I find the lack of information on this subject to be scandalous.
I have a vector - a 3D vector, ya know v:(x,y,z) which is from the origin. I need to get Euler (properly Cardan henceforth) angles that would rotate a point, say (1,0,0), to match that 3D vector. When I say Cardan angles, I mean explicitly one of these: XYZ, XZY, YXZ, YZX, ZXY, ZYX. The rotation order may be any one of these, so no locked into a particular rotation order methods.
No!! I cannot use quaternions or matrices or axis-angle or any other form. (PERIOD!) The deformation which I am forced to do *requires* (!!) Cardan angles since each axial rotation has a weight. So, no, don't bequest me to use quaternions or matrices or anything else. I need to convert a vector to Cardan Angles - I don't care if it involves quaternions, matrices, or axis-angles in between.
The start is a 3D vector. The end is Cardan angles that take an axially-aligned vector and rotate it so as to match that 3D vector.
And I know that there are two inevitable solutions (static frame and rotating frame). In this case, it should be safe to say that the frame is static - about the world coordinate system.
I've tried Shoemake's approach first converting the 3D vector into an axis-angle version (three-points - origin, axial vector, 3D vector), then to matrix. The results have not been correct. For this approach, definitely need more information to fill in the process.
This is a left-handed coordinate system with pre-concatenation of matrices, i.e.:
Matrix m = RotZ() * RotY() * RotX()
for an XYZ rotation matrix.
Anyone smart enough to figure that out?
Thanks,
Robert

Well, the rotation to come from one vector to another could be expressed by a axis-angle pair. An axis-angle pair can be converted into a rotation matrix. And I know that methods exists to compute Euler angles from rotation matrices. Perhaps there is a more direct way, but I would wonder if the above doesn't work in principle.

EDIT: Don't know how good this is, but look e.g. athttp://www.euclideanspace.com/maths/geometry/rotations/axisAngle/index.htmhttp://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htmhttp://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm

An axis vector can be rotated into the direction by first rotating along the world Y axis by the pitch, then by the Z by the yaw. But you probably know that already.

I don't think it's possible to have angles about each (world) axis that don't depend on the order of rotations, because changing the order of rotations with the same angles would give you a different direction. I don't know what a Cardan angle is though.

This'll probably just be a restatement of what's already been said, but:

- As Bob said above, the third angle is redundant when aligning one vector with another.

- You could use trig to compute the first two angles about whichever axes you're interested in, and leave the third as zero...

- Or you could construct the axis-angle matrix that rotates the first vector to the second and extract the angles from it.

I take it from your post that although you need (non-repeating) Euler angles as the final form, you can use other intermediate representations. If you wish to go through an axis-angle matrix representation, Shoemake's article/code is really the way to go. If you tried this and it didn't work, then there may be more to the problem, either that or we're misunderstanding it somehow. (One potential pitfall is using axis-angle and Euler-extraction functions with non-matching basis vector orientations, so watch out for this. FYI Shoemake's examples use column vectors.)

An axis vector can be rotated into the direction by first rotating along the world Y axis by the pitch, then by the Z by the yaw. But you probably know that already.

I don't think it's possible to have angles about each (world) axis that don't depend on the order of rotations, because changing the order of rotations with the same angles would give you a different direction. I don't know what a Cardan angle is though.

I've found that code and it sort of works, but because of the handedness of the system, modifications were necessary to get proper angles. But even this is not working in all cases. The problem is that the rotations are ordered, the first rotation is always a 'twist' (the roll) - but it is not always about the z-azis:

XYZ, XZY: roll = XYXZ, YZX: roll = YZXY, ZYX: roll = Z

Now, I may need to adjust for this. Haven't attempted it yet. These angles need to be ordered as they are being applied to geometry deformation that weights each axis rotation (e.g.):

Arbitrary rolls (because X or Y is actually a twist) may cause improper deformations. Again, I haven't had a chance to test all of these scenarios.

***

Cardan angles are the proper term for this subset of Euler angles - sometimes Euler angles are strictly applied to these rotation orders: XYX, XZX, YXY, YZY, ZXZ, ZYZ. Cardan angles do not repeat (check out Shoemake's "Euler Angle Conversion") as noted. Strictly speaking, they are not 'Euler angles', they are formally known as Cardan angles (sometimes Cardan-Bryant angles). But the term 'Euler angles' has become ubiquitous for all twelve of these rotation orders.

Note the switch of Z and X in calculating the Yaw (rAngle.y and eAngle.y). This may be a result of the system handedness being left (I don't know - noone discusses important details like this). Note also that the matrix concatenation is applied to 'eVec' (the vector that needs to match the other vector 'rVec'). This makes the Euler angles absolute with respect to rVec pointing along the (0d,0d,0d) rotation axis and so that the anti-rotation (negative eAngle.x and eAngle.y) would point eVec along it as well (as best that I can determine).

ETA: It is possible that I don't want to concatenate in rotation order, but use strict XYZ. Or it could be that I need to consider rotation order in the 'direction vector to Euler angles' as well. These are unknowns since noone ever talks about it. Quaternions are great, but sometimes you need to do things that cannot be done with them. These problems have existed for centuries, yet finding maths, algorithms, and source for something like this is impossible. Someone could really make a killing just writing a book exclusively on 3D rotations - it is the bane of all 3D and there are enough problems to cover an encyclopedia. :)

Original post by jykI take it from your post that although you need (non-repeating) Euler angles as the final form, you can use other intermediate representations. If you wish to go through an axis-angle matrix representation, Shoemake's article/code is really the way to go. If you tried this and it didn't work, then there may be more to the problem, either that or we're misunderstanding it somehow. (One potential pitfall is using axis-angle and Euler-extraction functions with non-matching basis vector orientations, so watch out for this. FYI Shoemake's examples use column vectors.)

Yes.

Shoemake's code seems to return some incorrect results in my case - rotation angles are usually correct, but in the wrong 'slot' (e.g.: z instead of x). Part of this could well be the translation from right-left and column:major-row:major - I'm working in a left-handled coordinate system (he uses right). My matrices are row major (he uses column major). Don't know how the SDK applies vectors (column or row). My guess is as row vectors. I'd have to look at their vector * matrix operator code and figure it out. The SDK that I'm using doesn't use Matrix [4][4] or [3][3]. Instead it uses this:

I'm still no closer to solving this. My gut feeling (which isn't as good as hard knowledge) is that in order to do this using the Z-axis as a standard Roll axis whereas my Roll axis varies, the two vectors will need to be such that the first (the target) or second (source) vector is more along the Z-axis than not (i.e.: rotate both vectors by 90d or 180d) so that any Roll that is not really a Roll in the ordered rotation is.

Not sure about that, but the code above (and modified just to multiply in RotX*RotY*RotZ order) doesn't always work as expected. I'm getting nearly +/-90d rolls when the vectors shouldn't be rolling. It makes for some rather nasty bend deformations.

If it weren't for these darned deformation rotations, I'd settle for axis-angle to matrix and be done with it. Alas, I need the Euler/Cardan rotations, and they need to be proper (however one defines that in this situation). To relieve some of the confusion as to why I don't seem to have full control here - this is taking the data from one 3D application and using it in another through a plugin. So, no, I don't have full control. Nor do I have full knowledge of how the source application works internally - I have almost none (and they are not using much standard anything it seems).

Taking the vector rVec and determining its main axis direction (if two values are the same, any of the two main axes will probably work similarly) tells me which axis to consider as the 'Roll' axis. Both vectors, rVec and eVec, are rotated so that their main axes (X or Y) are now the Z-axis. With that, I can calculate using the standard DirectionVector-to-EulerAngles maths. Then I just assign the Euler vector angles to the appropriate x,y,z. Now the rotations are 'minimal' and the 'Roll' axis as determined for the vector is always 0.0.

Tests so far have all been positive. There is a likelyhood of finding an exception to this - a vector with equal non-zero values like v(10,10,10) would prove an interesting situation - but it should default to standard Z-axis Roll for better or worse.