+5  A: 

Rich Seller's answer shows you how to rotate a point from one 3-D coordinate system to another system, given a set of Euler angles describing the rotation between the two coordinate systems.

But it sounds like you're asking for something different:

You have: 3-D coordinates of a single point

You want: a set of Euler angles

If that's what you're asking for, you don't have enough information. To find the Euler angles, you'd need coordinates of at least two points, in both coordinate systems, to determine the rotation from one coordinate system into the other.

You should also be aware that Euler angles can be ambiguous: Rich's answer assumes the rotations are applied to Z, then X', then Z', but that's not standardized. If you have to interoperate with some other code using Euler angles, you need to make sure you're using the same convention.

You might want to consider using rotation matrices or quaternions instead of Euler angles.

Jim Lewis
"you don't have enough information" .. haven't I already described the 2 points in 3D space? the 1st point is anything, and the 2nd point is 0,0,0 ... so I want to measure the Euler rotations between those 2 points in the order XYZ.
Jenko
Please consider updating your answer since I have edited my question and added a +500 bounty.
Jenko
A: 

Talking about the rotation of axes, I think step 3 should have been the rotation of X'-, Y''-, and Z'-axes about the Y''-axis.

+1  A: 

Here are my working assumptions:

  • The coordinate system (x,y,z) is such that positive x is to the right, positive y is down, and z is the remaining direction. In particular, y=0 is the ground plane.
  • An object at (0,0,0) currently facing towards (0,0,1) is being turned to face towards (x,y,z).
  • In order to accomplish this, there will be a rotation about the x-axis followed by one around the y-axis. Finally, there is a rotation about the z-axis in order to have things upright.

(The terminology yaw, pitch, and roll can be confusing, so I'd like to avoid using it, but roughly speaking the correspondence is x=pitch, y=yaw, z=roll.)

Here is my attempt to solve your problem given this setup:

rotx = Math.atan2( y, z )
roty = Math.atan2( x * Math.cos(rotx), z )
rotz = Math.atan2( Math.cos(rotx), Math.sin(rotx) * Math.sin(roty) )

Hopefully this is correct up to signs. I think the easiest way to fix the signs is by trial and error. Indeed, you appear to have gotten the signs on rotx and roty correct -- including a subtle issue with regards to z -- so you only need to fix the sign on rotz.

I expect this to be nontrivial (possibly depending on which octant you're in), but please try a few possibilities before saying it's wrong. Good luck!


Here is the code that finally worked for me.

I noticed a "flip" effect that occurred when the object moved from any front quadrant (positive Z) to any back quadrant. In the front quadrants the front of the object would always face the point. In the back quadrants the back of the object always faces the point.

This code corrects the flip effect so the front of the object always faces the point. I encountered it through trial-and-error so I don't really know what's happening!

 rotx = Math.atan2( y, z );
 if (z >= 0) {
    roty = -Math.atan2( x * Math.cos(rotx), z );
 }else{
    roty = Math.atan2( x * Math.cos(rotx), -z );
 }
A. Rex
So here's one misunderstanding I'm having. You say that your code works if the object is at y=0, but I can't understand how that would be the case. In that case you compute yaw=0 but pitch!=0, which doesn't seem right. (That's why I asked if z was up/down.) Any ideas?
A. Rex
Yes, it works because my object is some distance away from the point its facing and the only angle that really changes is yaw (rotation upon the Y axis, so the object rotates horizontally to face the point which is on the ground plane). Have I said anything confusing?
Jenko
@Rex - I've explained everything I can in my edited question, if you need anything more then please write back. Waiting for your updated code.
Jenko
@Rex - Thank you very much! correct answer!!! it works like a charm and my object correctly rotates to face the vector... phew!!! its been almost a week of struggling around trying to find the right answer.
Jenko
@Rex - One last problem however: During some X+Y rotations the object appears to be rotating on Z, such that the bottom of the object is not facing the ground plane. Can you calculate a Z rotation such that the object is always upright? I'm posting a video of my results.
Jenko
Well, I hope things worked out for you. PS. Watching that video is kind of fun.
A. Rex
Thanks very much :) it works as expected. You really are a god sent!!! Do you have any email that I can write to you at? You take minutes to solve things that others (and me) take weeks!!!
Jenko
Sorry, but the "A." in "A. Rex" stands for "Anonymous". Your best chance of catching me is randomly on Stack Overflow. I go through periods when I read this site and periods when I don't.
A. Rex
A: 

It really helps to have a clear head for figuring this stuff about. It is pointless to go straight to the math without a really clear picture of what you want to do. And this sort of stuff is guaranteed to get your brain in a twist, so you need to get the essentials.

Imagine you are sitting, with a closed book on your lap, with the sun setting over the sea ahead of you.

Now imagine you are told to hold the book out so that its front cover faces the setting sun. Now you would probably have the title text the right way up, but equally it could be upside down or sideways.

i.e. the task was not specified completely. The specification was too loose. And so you get not a unique solution but a solution set. A single degree of freedom.

To resolve into a unique solution, you need to give an additional constraint.

Lets say you supply the additional constraint that the writing be the correct way up.

Now the sun could be anywhere in the sky, and you will arrive at unique solution.

Anywhere, that is, apart from directly overhead/underneath. You would need to take this as a special case.

In fact two rotations would be sufficient.

Imagine you stick a long nail through the book so that its tip faces upwards. Let's say that is the Z axis.

Now your first rotation is about the axis of the nail. Imagine the book has a clock face printed on the cover, and the nail has come through the centre. Simply rotate until the shadow that the nail casts equals 12 o'clock on the clock face.

The second rotation is to lift the top of the book until the shadow has receded to a single point. this is actually rotating around the axis that is the bottom edge of your book. but you could equally well rotate around the line that joins the nine o'clock position to the three o'clock position. Let's say that is the X axis.

( Of course you would need to look carefully at the situation when the sun is beneath the horizon... maybe find a more apt analogy )

I wrote a ray tracer once, years back. And it consisted of tons of sticking pencils through the bits of paper, and chewing on abstract thought experiments.

Always start from a point you understand. Never be in a position where you're tweaking some magic formula that doesn't quite work. I got through a ton of A4 refill with this stuff. always start a fresh page if it gets murky.

Ohmu
I understand Euler rotations and the importance of rotation order perfectly well, but I can't be expected to understand exactly how the math behind Cartesian to Euler works. That's why I'm here asking for help.
Jenko
You can offer 1 million points in bounty, but to get an answer you need to ask an unambiguous question.
Ohmu
If the path of understanding deters you, I recommend this: State clearly what you want done. Don't try at this stage to implement it, because that will leave you asking a question about a broken implementation that probably didn't make sense in the first place. Just state the original problem. Unambiguously. In terms that you understand. Unequivocably.
Ohmu
Look at this post http://stackoverflow.com/questions/1251828/calculate-rotations-to-look-at-a-3d-point/4021898#4021898 - I've stated very clearly about what I need to calculate and why. Can I make it any simpler? Just need to calculate 2 angles, to rotate an object to face a point. Got it?
Jenko
I was born with it, thanks for asking. hmm I wonder who has downvoted me :) I noticed from the formulation of the question that there was a lack of understanding, hence I deliberately addressed my answer at a basic level. Little did I know that understanding was not a welcome contribution...
Ohmu
+2  A: 
Beta
@Beta - Thanks for your answer. Please see my edited question for my exact rotation system - and I don't really need them in terms of pitch/yaw but rather as rotation X and rotation Y (see my picture to know what I mean by that)
Jenko
I assume that x,y,z refer to a unit vector of the direction I'm trying to rotate towards?
Jenko
@Jenko: yes, that's correct.
Beta
I tried your solution but it isn't working for some reason. Too tired to figure out why since Rex's answer already works 99% of the time. Thanks very much though! and keep up the good work.
Jenko
I think I know the reason: YOUR DIAGRAMS ARE WRONG.
Beta
Well, that's being mean, and guess what, my diagrams are correct since Rex figured out the correct answer. Look at the updated code that finally worked for me, its similar to yours, no doubt but still its the one that worked.
Jenko