Cartesian to spherical coordinates

Started by
23 comments, last by Suen 11 years, 11 months ago
You do realize that you aren't using atan2, right? And you're not computing the atan at all, right? You aren't following the formula on Wikipedia. You need to use atan when converting from cartesian to spherical coordinates (and you really should use atan2, not just atan). As a side note, asinf returns a result in the range [-pi/2, +pi/2] which means your theta doesn't follow your invariant that it is in the range [0, 2*pi) (assuming you're using the normal asinf). (and as another side note, since you're using C++, you should probably just go with asin rather than asinf (functionally, they're the same though)).

Also, both functions you posted have the exact same function signature ([font=courier new,courier,monospace]glm::vec3 Camera::sphericalToCartesian(glm::vec3 sphericalCoordinate)[/font]).

What will help in debugging is doing simple conversions (try (0, 0, 1) (1, 0, 0) and (0, 1, 0) for cartesian to spherical (and (1/sqrt(3), 1/sqrt(3), 1/sqrt(3))).
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Advertisement

You do realize that you aren't using atan2, right? And you're not computing the atan at all, right? You aren't following the formula on Wikipedia. You need to use atan when converting from cartesian to spherical coordinates (and you really should use atan2, not just atan). As a side note, asinf returns a result in the range [-pi/2, +pi/2] which means your theta doesn't follow your invariant that it is in the range [0, 2*pi) (assuming you're using the normal asinf). (and as another side note, since you're using C++, you should probably just go with asin rather than asinf (functionally, they're the same though)).


I realize I am not using atan2, and in turn I'm not following the formula on wikipedia. I don't see how it relates to this. Bear with me; again the convention I used was this:

x = -cos(phi)*sin(theta)*r (1)
y = sin(phi)*r (2)
z = -cos(phi)*cos(theta)*r (3)

What I did was to derive theta and phi from these. From eq. 2 we can get phi:

phi = arcsin(y/r)

Inserting this in (1) we get:

theta = arcsin(-x/r*cos(phi))

and r is just the distance:

r = sqrt(x^2+y^2+z^2)

Where exactly does atan(atan2 to be more precise) come into this formula? Yes according to the formula in wikipedia arctan is used but I thought the formula for converting from cartesian to spherical coordinates depended on the convention you used when converting from spherical to cartesian coordinates. Do you mean to say that the formula described in wikipedia is always the one you use regardless of what convention you use when going from spherical to cartesian coordinates? A stupid question I know but this is how I understood it when you told me that atan need to be used when converting from cartesian to spherical coordinates.

Also out of curiosity, why should I use asin instead of asinf since I use C++? asin accept a double as an argument and return a double. I'm sending in a float value and expect a float value to be returned thus I used asinf.


Also, both functions you posted have the exact same function signature (glm::vec3 Camera::sphericalToCartesian(glm::vec3 sphericalCoordinate)).

What will help in debugging is doing simple conversions (try (0, 0, 1) (1, 0, 0) and (0, 1, 0) for cartesian to spherical (and (1/sqrt(3), 1/sqrt(3), 1/sqrt(3))).
[/quote]

Yikes...fixed it. This probably confused lots of you, my deepest apologies
I suggest you take a look at the derivation of the spherical coordinates from cartesian coordinates somewhere online, it explains step by step how it goes and where the atan comes in. Basically it arises as a simplifcation to multiple nested arcsin, cos, etc...

Coordinate systems have nothing to do with that, rather they transform the coordinate basis used by Wikipedia (which is by definition Z-up) into a coordinate basis relevant to the application you are using spherical coordinates for. It is not intrinsic to the spherical coordinates formula and just "rotates" the axes so that what is "up", "left", etc... in Wikipedia's coordinate system is also "up", "left", etc... in your program, and not something else. The formula itself is correct as long as you take care of properly defining what the angles and axes represent geometrically. The formula itself just maps two angles and a radius to a point on a sphere of the same radius. For the formula to actually be useable you need to define "sphere", that's where the coordinate basis comes in.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


*snip*

You might want to look at what asin returns. If it covered at least the range [-pi, +pi) (or [0, 2*pi)) in its return value, it may work, but it doesn't (not in C++ anyway). Because of this, both phi and theta will be in the range [-pi/2, +pi/2], which mean's you're restricting your spherical coordinates to only half the system and aren't covering the entire system. It doesn't create a bijection of the two coordinate systems.


Also out of curiosity, why should I use asin instead of asinf since I use C++? asin accept a double as an argument and return a double. I'm sending in a float value and expect a float value to be returned thus I used asinf.

Not if you're using C++. [font=courier new,courier,monospace]asin[/font] is overloaded in C++ to return what it's given (float, double, or long double). asinf is C, asin (the one I'm talking about, at least) is C++.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

I suggest you take a look at the derivation of the spherical coordinates from cartesian coordinates somewhere online, it explains step by step how it goes and where the atan comes in. Basically it arises as a simplifcation to multiple nested arcsin, cos, etc...

Coordinate systems have nothing to do with that, rather they transform the coordinate basis used by Wikipedia (which is by definition Z-up) into a coordinate basis relevant to the application you are using spherical coordinates for. It is not intrinsic to the spherical coordinates formula and just "rotates" the axes so that what is "up", "left", etc... in Wikipedia's coordinate system is also "up", "left", etc... in your program, and not something else. The formula itself is correct as long as you take care of properly defining what the angles and axes represent geometrically. The formula itself just maps two angles and a radius to a point on a sphere of the same radius. For the formula to actually be useable you need to define "sphere", that's where the coordinate basis comes in.


As you properly explained here the formula on wikipedia transform a coordinate from one coordinate basis to another. Looking at the definition in wikipedia the positive z-axis is up as you mentioned. This is a bit different in my case, where the positive y-axis is actually up. Basically it's the standard OpenGL way, positive y-axis is up, you then have the positive x-axis and then look along the negative z-axis. So to correspond for the difference here what would I do? Would I swap the values between y and z in the formula described on wiki? Because obviously just inserting the formula written there right into my code won't work due to these differences. My math skills are getting really rusty here...

Thank you for clarifying what I asked in my other question. I thought the two were connected to each other, that is if you have the formula for transforming a point from a spherical coordinate system to a cartesian system you could, from it, derive a formula for going from a cartesian coordinate system to a spherical coordinate system. Thus that's how I came to the conclusion of the formulas I posted above which I use in my code.

So basically, according to what you and Cornstalks said the way I thought is...completely untrue for my purpose? Since as you mentionted it is not instrinct to the spherical coordinate formula, and as Cornstalk mentioned arcsin returns a value in the range [-pi/2, +pi/2] so obviously just deriving the formulas the way I did is pretty much wrong.



[quote name='Suen' timestamp='1336868555' post='4939665']
*snip*

You might want to look at what asin returns. If it covered at least the range [-pi, +pi) (or [0, 2*pi)) in its return value, it may work, but it doesn't (not in C++ anyway). Because of this, both phi and theta will be in the range [-pi/2, +pi/2], which mean's you're restricting your spherical coordinates to only half the system and aren't covering the entire system. It doesn't create a bijection of the two coordinate systems.
[/quote]

This is what I suspected, when I wrote to Bacterius, about arcsin returning a value which would be in the range [-pi/2, +pi/2]. I probably did not explain myself clearly there. And yes of course it makes completely sense then to why my values are being restricted in my program.


Not if you're using C++. asin is overloaded in C++ to return what it's given (float, double, or long double). asinf is C, asin (the one I'm talking about, at least) is C++.

Thank you, helpful information (which I should have known beforehand if I payed more attention to these smaller details..). Will change it then.

I suggest you take a look at the derivation of the spherical coordinates from cartesian coordinates somewhere online, it explains step by step how it goes and where the atan comes in. Basically it arises as a simplifcation to multiple nested arcsin, cos, etc...


Quick update here. This probably belongs to the math section of this forum rather than the programming section but I feel it's unnecessary to start a whole new thread there because of this post only. Anyway I did a quick check to understand how it's derived and if you look at this picture this is how I thought:

spherical_coordinates.png


To get phi I looked at the triangle formed by the z-axis and the distance rho. Since both of these are known to us we can use:

cos(phi) = z-coord/rho => phi = arccos(z-coord/rho)

Similarly if you look at the xy-plane you can see a triangle formed by the x-axis and the distance rho projected on the xy-plane. Since both the x and y coordinate are known to us we can use:

tan(theta) = y/x => theta = arctan(y/x)

Correct me though if I am thinking wrong here.
Exactly and rho is r, the radius of the sphere, obtained via pythagoras, e.g. r = ||P||. The only difference from Wikipedia is that phi and theta are used a different way around, this is where you need to be careful. See on the Wikipedia page, phi represents the azimuth (horizontal direction) and theta the elevation (vertical direction). On this figure it's the other way around. I think this might have been the source of the confusion.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


Exactly and rho is r, the radius of the sphere, obtained via pythagoras, e.g. r = ||P||. The only difference from Wikipedia is that phi and theta are used a different way around, this is where you need to be careful. See on the Wikipedia page, phi represents the azimuth (horizontal direction) and theta the elevation (vertical direction). On this figure it's the other way around. I think this might have been the source of the confusion.


I did make sure to not mix these two so there should not be a problem there. Just so I have understood this correct; I am to use the formula described on wikipedia, but I need to account for that my "up" to me would be the y-coordinate as opposed to the z-coordinate in wikipedia?
I did make sure to not mix these two so there should not be a problem there. Just so I have understood this correct; I am to use the formula described on wikipedia, but I need to account for that my "up" to me would be the y-coordinate as opposed to the z-coordinate in wikipedia?[/quote]
Exactly, that's just it! In essence you apply the Wikipedia formula on your angles (which are in the same basis as Wikipedia as you just said), which will give you a cartesian coordinate for the corresponding point on the sphere, which will be in a coordinate system where Z is the "up" vector. At this point you rotate the basis so that the Y axis becomes the "up" vector, which boils down to swapping the Y and Z axis. You could do it in two distinct steps but it's equivalent to just use the Wikipedia formula and interchanging the equations for Y and Z.

It's possible to obtain the same result by using a different coordinate system for your two angles (e.g. doing the basis rotation on the spherical coordinates rather than cartesian), but it's less intuitive and in general prone to errors.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


I did make sure to not mix these two so there should not be a problem there. Just so I have understood this correct; I am to use the formula described on wikipedia, but I need to account for that my "up" to me would be the y-coordinate as opposed to the z-coordinate in wikipedia?

Exactly, that's just it! In essence you apply the Wikipedia formula on your angles (which are in the same basis as Wikipedia as you just said), which will give you a cartesian coordinate for the corresponding point on the sphere, which will be in a coordinate system where Z is the "up" vector. At this point you rotate the basis so that the Y axis becomes the "up" vector, which boils down to swapping the Y and Z axis. You could do it in two distinct steps but it's equivalent to just use the Wikipedia formula and interchanging the equations for Y and Z.

It's possible to obtain the same result by using a different coordinate system for your two angles (e.g. doing the basis rotation on the spherical coordinates rather than cartesian), but it's less intuitive and in general prone to errors.
[/quote]

I'm probably getting stupid here...that and I think I confused you. I mean there is nothing wrong with what you said, I agree with everything you said but to convert to cartesian coordinates work perfectly fine for me through the formula I am using (if you look at the code in the first post). What I don't get working is converting point in a cartesian coord. system to a spherical one. This is what I'm trying to do...and I thought the correct formula for this would be the one described in wikipedia.

Or did you actually mean that I should change my convetion and use the convention used in wikipedia to go from a spherical coordinate system to a cartesian coordinate system? That if I use it I get a cartesian coordinate and then swap the y and z axis accordingly (for my desired coord. system), and then just use the other formula described in wikipedia to go back to a spherical coordinate system? Is that what you meant?

This topic is closed to new replies.

Advertisement