# Cartesian to spherical coordinates

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

## Recommended Posts

I have two functions, one that converts spherical coordinates to cartesian coordinates and one that converts cartesian coordinates to spherical coordinates. The spherical to cartesian function works fine as far as I am concerned. But my cartesian to spherical function is acting really weird.

I describe my spherical coordinates as following: (r, theta, phi) where theta [0, 2*PI) and phi [0, PI]

I noticed the problem with my function as I was accumulating values to my theta. Basically I get locked to a theta value of 89-91. If I convert the following spherical coordinate (3.0f, 91.0f, 0.0f) to cartesian coordinates I get (-2.99954, 0, 0.0523535). If I now convert THIS cartesian coordinate back to spherical coordinates I get (3, 89.0001, 0) which is clearly wrong. It then just continues in an endless cycle...goes up to 91 and goes back to 89 from there. To summarize the problem:

Spherical coord. (3.0f, 91.0f, 0.0f) -> Cartesian coord. (-2.99954, 0, 0.0523535)
Cartesian coord. (-2.99954, 0, 0.0523535) -> Spherical coord. (3, 89.0001, 0)

I've taken a look at both functions but I can't really figure out where the problem lies. Here is the code to both functions:

Spherical to cartesian

 glm::vec3 Camera::sphericalToCartesian(glm::vec3 sphericalCoordinate) { GLfloat theta = degToRad(sphericalCoordinate.y); GLfloat phi = degToRad(sphericalCoordinate.z); glm::vec3 cartesianCoordinate(-cosf(phi)*sinf(theta), sinf(phi), -cosf(phi)*cos(theta)); return cartesianCoordinate * sphericalCoordinate.x; } 

Cartesian to spherical

 glm::vec3 Camera::cartesianToSpherical(glm::vec3 cartesianCoordinate) { GLfloat r = (sqrt(pow(cartesianCoordinate.x, 2) + pow(cartesianCoordinate.y, 2) + pow(cartesianCoordinate.z, 2))); GLfloat phi = (asinf(cartesianCoordinate.y/r)*180.0f)/PI; //GLfloat radPhi = degToRad(phi); //Necessary? GLfloat theta = (asinf(-cartesianCoordinate.x/(r*cosf(phi)))*180.0f)/PI; glm::vec3 sphericalCoordinate(r, theta, phi); return sphericalCoordinate; }  Edited by Suen

##### Share on other sites
What's the purpose of the degrees-to-radians conversions? All of the standard library trig functions operate in radians, so I'm not sure where your numbers in degrees are coming from in the first place?

##### Share on other sites

What's the purpose of the degrees-to-radians conversions? All of the standard library trig functions operate in radians, so I'm not sure where your numbers in degrees are coming from in the first place?

I'm not sure how to answer your question. I specify theta and phi in degrees and as you said the standard library trig. functions operate in radians so I need to convert these to radians before performing my calculations. If, say (r, 0, 0), would mean you are looking in the negative z-axis and the user change phi from 0 to 90 I would expect a rotation of 90 degrees, looking straight up.

##### Share on other sites

[quote name='ApochPiQ' timestamp='1336841328' post='4939592']
What's the purpose of the degrees-to-radians conversions? All of the standard library trig functions operate in radians, so I'm not sure where your numbers in degrees are coming from in the first place?

I'm not sure how to answer your question. I specify theta and phi in degrees and as you said the standard library trig. functions operate in radians so I need to convert these to radians before performing my calculations. If, say (r, 0, 0), would mean you are looking in the negative z-axis and the user change phi from 0 to 90 I would expect a rotation of 90 degrees, looking straight up.
[/quote]
I think ApochPiQ is asking why you're using degrees in the first place, not why you are converting them. Why not just use radians always?

As for your formulae, why not use the conversions from Wikipedia? Be sure to use atan2 instead of atan so you don't have to worry about divide by zero stuff.

##### Share on other sites

[quote name='Suen' timestamp='1336845526' post='4939601']
[quote name='ApochPiQ' timestamp='1336841328' post='4939592']
What's the purpose of the degrees-to-radians conversions? All of the standard library trig functions operate in radians, so I'm not sure where your numbers in degrees are coming from in the first place?

I'm not sure how to answer your question. I specify theta and phi in degrees and as you said the standard library trig. functions operate in radians so I need to convert these to radians before performing my calculations. If, say (r, 0, 0), would mean you are looking in the negative z-axis and the user change phi from 0 to 90 I would expect a rotation of 90 degrees, looking straight up.
[/quote]
I think ApochPiQ is asking why you're using degrees in the first place, not why you are converting them. Why not just use radians always?

As for your formulae, why not use the conversions from Wikipedia? Be sure to use atan2 instead of atan so you don't have to worry about divide by zero stuff.
[/quote]

Alright that was just to simplify it for myself. Two other tutorials I've followed a few weeks ago also made the same and since I used them as a starting point for what I wanted to do I just went with degrees. I could probably just use radians though yes.

As for your question, the thing is that I used another convention to have it in a specific way. What I have is the following:

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

and again it is (r, theta, phi) with the interval for theta and phi as described in my first post.

If I defined a spherical coord. (1, 0, 0) I want it to correspond to the negative z-axis which is exactly what I would get from the above: (0, 0, -1).
If I have spherical coord. (1, 0, 90) I would visualize that as my point moving up to the north pole on the sphere thus I would expect to look straight up in the positive y-axis and again with the above it gives me (0, 1, 0). Having spherical coord (1, 90, 0) would give me (1, 0, 0) and so on

The convention used in wikipedia would not give me this. For example (1, 90, 0) would give me (0, 0, 1) from the wikipedia page.

##### Share on other sites
The convention used in wikipedia would not give me this. For example (1, 90, 0) would give me (0, 0, 1) from the wikipedia page.[/quote]
It's perfectly valid to shuffle around which formula corresponds to which coordinate, so that it matches the coordinate system you are interested in. Just make sure you don't turn a cos into a sin by accident or something like that.

##### Share on other sites

The convention used in wikipedia would not give me this. For example (1, 90, 0) would give me (0, 0, 1) from the wikipedia page.

It's perfectly valid to shuffle around which formula corresponds to which coordinate, so that it matches the coordinate system you are interested in. Just make sure you don't turn a cos into a sin by accident or something like that.
[/quote]

This is what confused me quite a bit at first. However I got some excellent help with it twice (second time was more of an explanation here on gamedev) so the formula I use now should be fine. I've tried it and it worked as I wanted it. In fact I already have a working solution for what I want to do but I didn't use a cartesian to spherical conversion there. Anyway I thought it would be good (someday in the future) to have a properly working function.

Does it have something to do perhaps with arcsin returning a limit between PI/2 and -PI/2?

##### Share on other sites
Does it have something to do perhaps with arcsin returning a limit between PI/2 and -PI/2?[/quote]
? No, there are just many coordinate systems in use, for instance XY horizontal plane and Z vertical axis, XZ horizontal plane and Y vertical axis, sometimes the Z axis goes in the negative direction, etc... these are all conventions and you just need to transform the formula from the coordinate system used by Wikipedia into the coordinate system you are using, otherwise it doesn't make sense. The formula is equivalent, it is just in a different (no less valid) coordinate system.

For instance the conventional "up" vector would be (0, 1, 0) in a coordinate system where Y is the vertical axis, if you were to import a model containing such vectors in an application which uses a coordinate system where Z is the vertical axis, you would need to transform the vector to one coordinate system to the other so that it still correctly points upwards, in this case it would involve swapping the Y and Z coordinates, so the new vector would be (0, 0, 1) which is correct.

##### Share on other sites
My point is you're converting degrees to radians, then feeding the resulting numbers (which are in radians) back into the degree-to-radian conversion functions. I'm not sure how you expect this to work, but it will always produce incorrect results, because you never convert back to degrees anywhere.

 Don't mind me, I can't read. You are indeed converting back to degrees. It just seems really wasteful to go back and forth all the time and it's going to complicate your math and lead to incorrect conversions like this if you happen to make a mistake. Edited by ApochPiQ

##### Share on other sites

Does it have something to do perhaps with arcsin returning a limit between PI/2 and -PI/2?

? No, there are just many coordinate systems in use, for instance XY horizontal plane and Z vertical axis, XZ horizontal plane and Y vertical axis, sometimes the Z axis goes in the negative direction, etc... these are all conventions and you just need to transform the formula from the coordinate system used by Wikipedia into the coordinate system you are using, otherwise it doesn't make sense. The formula is equivalent, it is just in a different (no less valid) coordinate system.

For instance the conventional "up" vector would be (0, 1, 0) in a coordinate system where Y is the vertical axis, if you were to import a model containing such vectors in an application which uses a coordinate system where Z is the vertical axis, you would need to transform the vector to one coordinate system to the other so that it still correctly points upwards, in this case it would involve swapping the Y and Z coordinates, so the new vector would be (0, 0, 1) which is correct.
[/quote]

Alright, this is how I understood it as well. Well basically that's what I've been doing, transforming the formula in wiki (and many other materials) to one suited for my need. I had a hard time understanding first though how all of these can be equivalent and still get confused by it from time to time

My point is you're converting degrees to radians, then feeding the resulting numbers (which are in radians) back into the degree-to-radian conversion functions. I'm not sure how you expect this to work, but it will always produce incorrect results, because you never convert back to degrees anywhere.

 Don't mind me, I can't read. You are indeed converting back to degrees. It just seems really wasteful to go back and forth all the time and it's going to complicate your math and lead to incorrect conversions like this if you happen to make a mistake.

As you said it's most likely wasteful and it will eventually lead to incorrect conversions (as can be seen in the data below). But I don't see how this is keeping it locked at 90-91 degrees.

This is a wild guess but while I checked the data printed out by the conversion the problem seem to be when my z-coordinate gets to really low values..that and it never goes below zero. It gets really weird, I'll print out some values to show. First two lines show the current stored coordinate in both cartesian and spherical form. The two following ones shows the stored coordinate after adding one to theta.

Cartesian coord: (-2.89778, 0, -0.776461)
Spherical coord: (3, 75, 0)

Spherical coord.(after adding 1 to theta): (3, 76, 0)
Cartesian coord.(after adding 1 to theta): (-2.91089, 0, -0.72577)

Cartesian coord: (-2.91089, 0, -0.72577)
Spherical coord: (3, 76, 0)

Spherical coord.(after adding 1 to theta): (3, 77, 0)
Cartesian coord.(after adding 1 to theta): (-2.92311, 0, -0.674858)

Cartesian coord: (-2.92311, 0, -0.674858)
Spherical coord: (3, 77, 0)

Spherical coord.(after adding 1 to theta): (3, 78, 0)
Cartesian coord.(after adding 1 to theta): (-2.93444, 0, -0.62374)

Cartesian coord: (-2.93444, 0, -0.62374)
Spherical coord: (3, 78, 0)

Spherical coord.(after adding 1 to theta): (3, 79, 0)
Cartesian coord.(after adding 1 to theta): (-2.94488, 0, -0.572432)

Cartesian coord: (-2.94488, 0, -0.572432)
Spherical coord: (3, 79, 0)

Spherical coord.(after adding 1 to theta): (3, 80, 0)
Cartesian coord.(after adding 1 to theta): (-2.95442, 0, -0.52095)

Cartesian coord: (-2.95442, 0, -0.52095)
Spherical coord: (3, 80, 0)

Spherical coord.(after adding 1 to theta): (3, 81, 0)
Cartesian coord.(after adding 1 to theta): (-2.96306, 0, -0.469309)

Cartesian coord: (-2.96306, 0, -0.469309)
Spherical coord: (3, 81, 0)

Spherical coord.(after adding 1 to theta): (3, 82, 0)
Cartesian coord.(after adding 1 to theta): (-2.9708, 0, -0.417525)

Cartesian coord: (-2.9708, 0, -0.417525)
Spherical coord: (3, 82, 0)

Spherical coord.(after adding 1 to theta): (3, 83, 0)
Cartesian coord.(after adding 1 to theta): (-2.97764, 0, -0.365614)

Cartesian coord: (-2.97764, 0, -0.365614)
Spherical coord: (3, 83, 0)

Spherical coord.(after adding 1 to theta): (3, 84, 0)
Cartesian coord.(after adding 1 to theta): (-2.98357, 0, -0.313591)

Cartesian coord: (-2.98357, 0, -0.313591)
Spherical coord: (3, 83.9999, 0)

Spherical coord.(after adding 1 to theta): (3, 84.9999, 0)
Cartesian coord.(after adding 1 to theta): (-2.98858, 0, -0.261474)

Cartesian coord: (-2.98858, 0, -0.261474)
Spherical coord: (3, 85, 0)

Spherical coord.(after adding 1 to theta): (3, 86, 0)
Cartesian coord.(after adding 1 to theta): (-2.99269, 0, -0.209275)

Cartesian coord: (-2.99269, 0, -0.209275)
Spherical coord: (3, 85.9999, 0)

Spherical coord.(after adding 1 to theta): (3, 86.9999, 0)
Cartesian coord.(after adding 1 to theta): (-2.99589, 0, -0.157014)

Cartesian coord: (-2.99589, 0, -0.157014)
Spherical coord: (3, 86.9999, 0)

Spherical coord.(after adding 1 to theta): (3, 87.9999, 0)
Cartesian coord.(after adding 1 to theta): (-2.99817, 0, -0.104707)

Cartesian coord: (-2.99817, 0, -0.104707)
Spherical coord: (3, 87.9998, 0)

Spherical coord.(after adding 1 to theta): (3, 88.9998, 0)
Cartesian coord.(after adding 1 to theta): (-2.99954, 0, -0.0523715)

Cartesian coord: (-2.99954, 0, -0.0523715)
Spherical coord: (3, 88.9997, 0)

Spherical coord.(after adding 1 to theta): (3, 89.9997, 0)
Cartesian coord.(after adding 1 to theta): (-3, 0, -1.77503e-005)

Cartesian coord: (-3, 0, -1.77503e-005)
Spherical coord: (3, 90.0001, 0)

Spherical coord.(after adding 1 to theta): (3, 91.0001, 0)
Cartesian coord.(after adding 1 to theta): (-2.99954, 0, 0.0523574)

Cartesian coord: (-2.99954, 0, 0.0523574)
Spherical coord: (3, 89.0001, 0)

Spherical coord.(after adding 1 to theta): (3, 90.0001, 0)
Cartesian coord.(after adding 1 to theta): (-3, 0, 2.63453e-006)

Cartesian coord: (-3, 0, 2.63453e-006)
Spherical coord: (3, 90.0001, 0)

Spherical coord.(after adding 1 to theta): (3, 91.0001, 0)
Cartesian coord.(after adding 1 to theta): (-2.99954, 0, 0.0523574) Edited by Suen

##### Share on other sites
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))). Edited by Cornstalks

##### Share on other sites

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

##### Share on other sites
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.

##### Share on other sites

*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++. Edited by Cornstalks

##### Share on other sites

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.

##### Share on other sites

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:

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.

##### Share on other sites
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. Edited by Bacterius

##### Share on other sites

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?

##### Share on other sites
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. Edited by Bacterius

##### Share on other sites

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?

##### Share on other sites
Ah, I see, well it's the same reasoning. In that case, taking it slowly, you want to convert your cartesian coordinates into the Wikipedia basis, e.g. by swapping the Y and Z axis once again, and then apply the inverse formula on Wikipedia's page. This will return two angles phi and theta as well as a radius. The radius is a scalar and as such only depends on the coordinate system's metric which is almost always constant, so it can remain the same, and the two angles phi and theta returned will describe azimuth and elevation respectively, and these "elevation", "azimuth" terms are coherent with *your* coordinate system because of the initial basis conversion at the beginning (swapping the two axes).

And no you don't need to go back and forth, all you need to do is ensure you give meaningful coordinates to the Wikipedia formula, since it assumes a Z-up coordinate system. As long as you keep that in mind and feed the formula will the correct coordinates, it will give you the right angles.

If all else fails, you could find the formulae online which use a Y-up coordinate system so there will be no confusion, but that's not as much fun!

I think I'm not expressing myself too well here it's not the easiest concept to put into words.

##### Share on other sites

Ah, I see, well it's the same reasoning. In that case, taking it slowly, you want to convert your cartesian coordinates into the Wikipedia basis, e.g. by swapping the Y and Z axis once again, and then apply the inverse formula on Wikipedia's page. This will return two angles phi and theta as well as a radius. The radius is a scalar and as such only depends on the coordinate system's metric which is almost always constant, so it can remain the same, and the two angles phi and theta returned will describe azimuth and elevation respectively, and these "elevation", "azimuth" terms are coherent with *your* coordinate system because of the initial basis conversion at the beginning (swapping the two axes).

And no you don't need to go back and forth, all you need to do is ensure you give meaningful coordinates to the Wikipedia formula, since it assumes a Z-up coordinate system. As long as you keep that in mind and feed the formula will the correct coordinates, it will give you the right angles.

If all else fails, you could find the formulae online which use a Y-up coordinate system so there will be no confusion, but that's not as much fun!

I think I'm not expressing myself too well here it's not the easiest concept to put into words.

You are in fact explaining yourself very well and I greatly appreciate it. Basically it is what you said, I want to convert my cartesian coordinates into the Wikipedia basis so they are described by the radial distance, azimuth and elevation. I assume this is exactly the same basis I am using, with the exception that I've changed the meaning of theta and phi (theta being the azimuth and phi being elevation as opposed to wikipedia which has the opposite). As you also mentioned, since up to me is the positive Y and not positive Z then these two need to be swapped in the inverse formula on Wikipedia's page.

Considering the above this is how I described the inverse formula on Wikipedia's page to myself (again Y and Z have to be swapped, theta and phi have to be swapped):

r = |p|
theta = arctan(z/x)
phi = arccos(y/r)

I'm not sure if this is the correct way to go about it though and I can't unfortunately try it at this very moment.

I could of course search and see if I can find a formula online which use y-up coordinate system but I wouldn't learn anything from that

##### Share on other sites
Bumping back this thread due to being away for a couple of days and not being able to try the formula in my reply above. Basically this is what I did:

Spherical coordinate (3.0, 0.0, 0.0) -> Cartesian coordinate (0, 0, -3)

The above is correct according the convention I use.

Now using the formula in my previous reply to convert back to spherical coordinates gave me this:

Cartesian coordinate (0, 0, -3) -> Spherical Coordinate (3, -1.5708, 1.5708)

which is of course wrong. Note that in spherical coordinates (3, 0, 0) = (r, azimuth, elevation).

So...I'm pretty much back to where I started (aside from all extra knowledge I've gotten in this thread, thanks guys!). Any suggestions?

##### Share on other sites
It sounds like your problem is your convention. Is there a particular reason you're using your particular convention for spherical coordinates, and not something a little more standard? Spherical coordinate (3, 0, 0) != Cartesian coordinate (0, 0, -3) if using standard conventions (it's (0, 0, 3)).

If you can understand the standard convention's formulas, but you can't translate them into your own custom conventions, you should probably just stick with the standard conventions. Edited by Cornstalks

##### Share on other sites

It sounds like your problem is your convention. Is there a particular reason you're using your particular convention for spherical coordinates, and not something a little more standard? Spherical coordinate (3, 0, 0) != Cartesian coordinate (0, 0, -3) if using standard conventions (it's (0, 0, 3)).

If you can understand the standard convention's formulas, but you can't translate them into your own custom conventions, you should probably just stick with the standard conventions.

Yes most likely the convetion is the problem. There is no important reason to why I choose it, it was just easier for me to visualize things with that convention thus I went with it. Furthermore it would have been interesting to know how to solve the problem but again this is not the right forum section for that. Either way I decided to just change the convention to the standard one described in wikipedia(or wolfram).

I got confused by the result (using the standard convention) at first as nothing seemed to make sense but I pretty much got it working in the end. I did swap the y and z-coordinate in the formula so it would correspond to my coordinate system but then I forgot that I am actually looking in the negative z-axis and not the positive one as in the formula, furthermore when converting back to cartesian coordinates I had to obviously swap the y and z coordinates there as well, which I also forgot to do. Simple mistakes which led to loads of confusion. Anyhow it works pretty fine now, with both conversion functions. Thanks for the help. Edited by Suen