В чем отличие от atan(y/x) и atan2(y,x) в OpenGL GLSL

У меня есть некоторые проблемы с пониманием результата функции atan в glsl. Документация также отсутствует.

Например, мне нужно преобразовать вершину в сферические координаты, преобразовать радиус сферической координаты, а затем преобразовать его обратно в декартовы координаты. Я использую следующее преобразование вершин икосферы радиуса 2 с центром в 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;
}

но результат будет другим, если я использую atan(y/x) или atan2(y,x). Я поставил маленькую константу 1E-18, чтобы избежать полюса.

Почему такое поведение? Я предполагаю, что значение, возвращаемое atan(y/x) и atan2(y,x), имеет разный диапазон. В частности, в этой реализации я думаю, что theta должно варьироваться от [0-Pi], а Phi - от [0,2Pi].

Я прав? Существуют ли более численно точные реализации преобразований сферических координат?


person linello    schedule 11.09.2014    source источник


Ответы (1)


atan2 правильно учитывает все 4 квадранта и может иметь дело с x==0.

atan2(-1,-1) правильно возвращает -3/4*PI, а atan(-1/-1) возвращает 1/4*PI

person ratchet freak    schedule 11.09.2014
comment
Так должен ли я придерживаться atan2 для правильного преобразования сферических координат? - person linello; 11.09.2014
comment
@linello Да, ты должен. atan полезен только в том случае, если у вас нет координат, и даже в этом случае его следует использовать с осторожностью. - person Arpegius; 11.09.2014
comment
Как ни странно, opengl.org/sdk/docs/man/html/atan. xhtml на самом деле говорит, что для atan(y,x) результаты не определены, если x равен нулю. Кажется вероятным, что это ошибка документации; atan(y,x) почти бесполезен, если он верен. - person david van brink; 15.11.2014
comment
@davidvanbrink раздел 8.1 документа спецификации (ссылка в формате pdf) говорит, что результаты не определены, если x и y оба равны 0, что снова делает его полностью полезным. - person ratchet freak; 17.12.2014
comment
Вау! Порядок восстановлен. - person david van brink; 17.12.2014
comment
в OpenGL нет atan2 shaderific.com/glsl-functions - person v.oddou; 07.09.2018
comment
@v.oddou это потому, что atan перегружен версией, которая принимает 1 параметр, и версией, которая принимает 2 параметра. Версия с 2 параметрами имеет ту же спецификацию, что и типичная версия atan2. - person ratchet freak; 07.09.2018