3

I've some problems in understanding the result of the function atan in glsl. Documentation is also lacking.

For example I need to convert a vertex to spherical coordinates, transform the radius of the spherical coordinate and then convert it back to cartesian coordinates. I'm using the following transformation on the vertices of an icosphere of radius 2 centered in 0.

vec3 to_sphere(vec3 P)
{
    float r = sqrt(P.x*P.x + P.y*P.y + P.z*P.z);
    float theta = atan(P.y,(P.x+1E-18));
    float phi= acos(P.z/r); // in [0,pi]
    return vec3(r,theta, phi);
}

vec3 to_cart(vec3 P)
{
    float r = P.x;
    float theta = P.y;
    float phi = P.z;
    return r * vec3(cos(phi)*sin(theta),sin(phi)*sin(theta),cos(theta);
}

void main()
{
    vec4 V = gl_Vertex.xyz;
    vec3 S = to_sphere(V.xyz);
    S.x += S.y;
    V.xyz = to_cartesian(S);

    gl_Position = gl_ModelViewProjectionMatrix * V;
}

but the result is different if I use atan(y/x) or atan2(y,x). I've put the small 1E-18 constant in order to avoid a pole.

Why this behaviour? I'm supposing that the value returned by atan(y/x) and atan2(y,x) has different range. In particular in this implementation I think that theta should range from [0-Pi] while Phi ranges in [0,2Pi].

Am I right? Are there more numerically precise implementations of spherical coordinates transformations?

linello
  • 8,451
  • 18
  • 63
  • 109

1 Answers1

8

atan2 properly accounts for all 4 quadrants and can deal with x==0.

atan2(-1,-1) properly returns -3/4*PI while atan(-1/-1) would return 1/4*PI

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • So should I stick with atan2 for proper spherical coordinate transformations? – linello Sep 11 '14 at 08:59
  • @linello Yes you should. atan is only useful if you don’t have coordinates, and even then should be used with caution. – Arpegius Sep 11 '14 at 11:00
  • Bizarrely, https://www.opengl.org/sdk/docs/man/html/atan.xhtml actually says for atan(y,x), "Results are undefined if x is zero." It seems likely that's a documentation mistake; atan(y,x) is nearly useless if true. – david van brink Nov 15 '14 at 17:44
  • 4
    @davidvanbrink [the spec document section 8.1 (pdf link)](https://www.opengl.org/registry/doc/GLSLangSpec.4.50.pdf#page=144) says "Results are undefined if x and y are both 0" which makes it fully useful again. – ratchet freak Dec 17 '14 at 14:11
  • 1
    Whew! Order is restored. – david van brink Dec 17 '14 at 15:01
  • there is no `atan2` in OpenGL http://www.shaderific.com/glsl-functions/ – v.oddou Sep 07 '18 at 07:16
  • @v.oddou that's because atan is overloaded with a version that takes 1 param and a version that takes 2 params. The 2 param version has the same specification as the typical atan2. – ratchet freak Sep 07 '18 at 08:08