Vector to Polar?

Recommended Posts

Atrix256    539
Hey Guys, I have a unit vector describing a directional light's direction and i want to convert it to polar to be shown in my editor as a pitch and yaw value, then when those values are changed, convert it back into a vector and store it as the light's direction. My math is doing all sorts of crazy stuff and is just not right at all (like if i put in 1.57 radians (90 degrees), it converts it to a vector, then converts it back to polar to update the editor display and it's showing up as 3.14 radians (180 degrees), not 1.57 (90 degrees)!) If it matters, in my X,Y,Z system, Y is the up and down axis. Here's my math, does it look right to you guys? BTW the light direction vector comes in normalized so I don't think it's a normalization issue. Also I removed all of the radians to degrees conversion stuff so am only working in radians and the problems are still happening so i dont think it's a conversion issue. //convert from vector to polar float fYaw = atan2(vLightDir.z,vLightDir.x); float fPitch = acos(vLightDir.y); //convert from polar to vector vLightDir.x = cos(fYaw)*sin(fPitch); vLightDir.z = sin(fYaw)*sin(fPitch); vLightDir.y = cos(fPitch); Thanks!

Share on other sites
haegarr    7372
Well, "polar" decribes a 2D co-ordinate, namely a radius and an angle. What you actually mean is a "spherical" co-ordinate, consisting of a radius and 2 angles.

That said, the math seems me correct.

Share on other sites
Atrix256    539
Thanks, yeah i do mean spherical coordinates thanks for the terminology fix.

It might help me scour google better.

But hey check out how the math works, let's say we had a yaw of 90 degrees and a pitch of 0 degrees and we are trying to convert it to a vector again:

//convert from polar to vector
vLightDir.x = cos(fYaw)*sin(fPitch);
vLightDir.z = sin(fYaw)*sin(fPitch);
vLightDir.y = cos(fPitch);

plugging in the numbers you get (working in degrees for easier reading):

vLightDir.x = cos(90) * sin(0);
vLightDir.z = sin(90) * sin(0);
vLightDir.y = cos(0);

that means...

vLightDir.x = 0 * 0
vLightDir.z = 1 * 0
vLightDir.y = 1

so... the vector out is 0,1,0

which is really 0 yaw and 90 degrees pitch since Y is the up vector.

it seems something is messed up but i'm not sure what

Share on other sites
haegarr    7372
The math isn't messed up. The only thing is that you named the angles the one way but uses a convention for interpretation the other way (AFAIS).

I.e. exchange the naming of yaw and pitch

vLightDir.x = cos(fPitch)*sin(fYaw);
vLightDir.z = sin(fPitch)*sin(fYaw);
vLightDir.y = cos(fYaw);

and you get for your example

vLightDir.x = cos(0°)*sin(90°) == 1
vLightDir.z = sin(0°)*sin(90°) == 0
vLightDir.y = cos(90°) == 0

EDIT: Hmmm. I must think another minute about this. Computing yaw from the xz seems me correct, too.

[Edited by - haegarr on March 28, 2010 1:54:37 PM]

Share on other sites
haegarr    7372
The (original) math seems me still correct. So the only explanation is still: Spherical angles cannot be interpreted like Euler angles.

Share on other sites
jyk    2094
Quote:
 it seems something is messed up but i'm not sure what
Your code treats a pitch of 0 as straight up, which may be causing you problems. Try this instead:
//convert from vector to polarfloat fYaw = atan2(vLightDir.z,vLightDir.x);float fPitch = asin(vLightDir.y);//convert from polar to vectorvLightDir.x = cos(fYaw)*cos(fPitch);vLightDir.z = sin(fYaw)*cos(fPitch);vLightDir.y = sin(fPitch);
Note also that:

1. To be fully correct, when converting from vector to spherical form, it should be handled as a special case when the vector is parallel or nearly parallel to the up vector.

2. You should clamp the input to asin() to the range [-1, 1] to correct for possible numerical error.