【问题标题】:What is the difference from atan(y/x) and atan2(y,x) in OpenGL GLSLOpenGL GLSL 中的 atan(y/x) 和 atan2(y,x) 有什么区别
【发布时间】:2014-11-05 03:12:52
【问题描述】:

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

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

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]

我说的对吗?是否有更精确的球坐标变换实现方式?

【问题讨论】:

    标签: opengl math glsl coordinate-transformation atan2


    【解决方案1】:

    atan2 正确占了所有 4 个象限,可以处理x==0

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

    【讨论】:

    • 那么我应该坚持使用 atan2 进行正确的球坐标变换吗?
    • @lineello 是的,你应该这样做。 atan 仅在您没有坐标时才有用,即便如此也应谨慎使用。
    • 奇怪的是,opengl.org/sdk/docs/man/html/atan.xhtml 实际上对 atan(y,x) 说,“如果 x 为零,则结果未定义。”这似乎是一个文档错误;如果为真,atan(y,x) 几乎没用。
    • @davidvanbrink the spec document section 8.1 (pdf link) 说“如果 x 和 y 都为 0,则结​​果未定义”这使得它再次完全有用。
    • 哇!订单已恢复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多