2014-09-11 283 views
3

我在理解glsl中atan函數的結果時遇到了一些問題。文件也缺乏。OpenGL GLSL中的atan(y/x)和atan2(y,x)有什麼區別

例如,我需要將頂點轉換爲球座標,轉換球座標的半徑,然後將其轉換回笛卡爾座標。我使用中心半徑2的icosphere的頂點下列轉換在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]

對嗎?是否有更精確的球座標轉換實現?

回答

7

atan2正確佔所有4個象限,可以處理x==0

atan2(-1,-1)正常返回-3/4*PIatan(-1/-1)將返回1/4*PI

+0

所以我應該堅持ATAN2進行適當的球面座標轉換? – linello 2014-09-11 08:59:03

+0

@linello是的,你應該。 atan只在沒有座標時纔有用,即使這樣也應謹慎使用。 – Arpegius 2014-09-11 11:00:16

+0

奇怪的是,https://www.opengl.org/sdk/docs/man/html/atan.xhtml實際上爲atan(y,x)表示,「如果x爲零,結果是不確定的。」這似乎是一個文檔錯誤;如果真的話,atan(y,x)幾乎是無用的。 – 2014-11-15 17:44:08

相關問題