我在理解glsl函数atan的结果时遇到了一些问题。也缺少文档。

例如,我需要将顶点转换为球坐标,转换球坐标的半径,然后将其转换回笛卡尔坐标。我在以2为中心的半径为2的icocosphere的顶点上使用以下转换。

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]范围内。

我对吗?球形坐标变换在数值上是否有更精确的实现?

最佳答案

atan2正确说明了所有四个象限,并且可以处理x==0

atan2(-1,-1)正确返回-3/4*PI,而atan(-1/-1)将返回1/4*PI

关于opengl - 与OpenGL GLSL中的atan(y/x)和atan2(y,x)有什么区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25782895/

10-09 09:00