2016-06-11 99 views
0

我正在嘗試開發一個簡單的光線追蹤器,並且獲得了球體,平面和圓錐體,但我面臨的問題是無法包裹頭部。 我嘗試了無限圓柱體的幾種不同的公式,並且所有那些應該考慮旋轉的人使得當使用不是0或1的旋轉並且僅在一個軸上時「退化」...例如:光線追蹤圓筒在旋轉時退化

0,0,1的作品,但0,0,0.5給我一個橢球體和0,1,1給我一個雙曲面...

這裏是我用來與射線相交的代碼。

enum e_bool test_intersect(double t[2], double *current_z) 
{ 
    enum e_bool retvalue; 

    retvalue = false; 
    if ((t[0] > DOUBLE_ZERO) 
    && (t[0] < *(current_z) || double_equal(*(current_z), t[0]))) 
    { 
     *(current_z) = t[0]; 
     retvalue = true; 
    } 
    if (!double_equal(t[0], t[1]) 
    && (t[1] > DOUBLE_ZERO) 
    && (t[1] < *(current_z) || double_equal(*(current_z), t[1]))) 
    { 
     *(current_z) = t[1]; 
     retvalue = true; 
    } 
    return (retvalue); 
} 

enum e_bool intersect_cylinder(t_primitive cp, t_ray r, double *current_z) 
{ 
    t_vec3 eye = vec3_substract(r.origin, cp.position); 
    double a = vec3_dot(r.direction, r.direction) - pow(vec3_dot(r.direction, cp.direction), 2); 
    double b = 2 * (vec3_dot(r.direction, eye) - vec3_dot(r.direction, cp.direction) * vec3_dot(eye, cp.direction)); 
    double c = vec3_dot(eye, eye) - pow(vec3_dot(eye, cp.direction), 2) - cp.radius * cp.radius; 
    double t[2]; 
    double delta; 
    delta = sqrt((b * b) - (4.0 * a * c)); 
    if (delta < 0) 
     return (false); 
    t[0] = (-b - (delta))/(2.0 * a); 
    t[1] = (-b + (delta))/(2.0 * a); 
    return (test_intersect(t, current_z)); 
} 

Here is the cylinder with a rotation of 1, 0, 0

Here it is with a rotation of 1, 1, 0

我缺少什麼,這個問題是視角或等距光線投射相同的,所以它與交集算法做的,但我不能找到有什麼不對...

回答

0

我在閱讀這些網頁後發現了我的問題的解決方案(gamedev幫了我很多忙):

http://mrl.nyu.edu/~dzorin/cg05/lecture12.pdf

http://www.gamedev.net/topic/467789-raycylinder-intersection/

我重新做了我的交叉點式,像這樣和它的正常工作:

enum e_bool intersect_cylinder(t_primitive cp, t_ray r, double *current_z) 
{ 
    t_vec3 pdp = vec3_substract(cp.direction, cp.position); 
    t_vec3 eyexpdp = vec3_cross(vec3_substract(r.origin, cp.position), pdp); 
    t_vec3 rdxpdp = vec3_cross(r.direction, pdp); 
    float a = vec3_dot(rdxpdp, rdxpdp); 
    float b = 2 * vec3_dot(rdxpdp, eyexpdp); 
    float c = vec3_dot(eyexpdp, eyexpdp) - (cp.radius * cp.radius * vec3_dot(pdp, pdp)); 
    double t[2]; 
    double delta; 
    delta = sqrt((b * b) - (4.0 * a * c)); 
    if (delta < 0) 
     return (false); 
    t[0] = (-b - (delta))/(2.0 * a); 
    t[1] = (-b + (delta))/(2.0 * a); 
    return (test_intersect(t, current_z)); 
} 

現在我的法線是錯誤的,但是這不是什麼大不了的問題來解決的。