2016-06-11 20 views
0

Ich versuche einen einfachen Raytracer zu entwickeln und habe Sphäre, Ebene und Kegel richtig gemacht, aber ich stehe vor einem Problem, mit dem ich mich nicht herumschlagen kann. Ich habe mehrere verschiedene Formeln für den unendlichen Zylinder ausprobiert und alle, die die Drehung berücksichtigen sollen, machen es "entartet", wenn eine Drehung verwendet wird, die nicht 0 oder 1 und nur eine Achse ist ... Zum Beispiel:Ray tracing cylinder degeneriert, wenn er gedreht wird

0,0,1 funktioniert, aber 0,0,0,5 gibt mir eine Ellipsoidkugel und 0,1,1 gibt mir einen Hyperboloid ...

Hier ist der Code, den ich benutze, um den Strahl mit dem Zylinder zu schneiden.

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

Was bin ich fehlt, das Problem ist das gleiche mit Perspektive oder isometrischen Strahlwerfprozessoren, so dass es mit dem Schnitt Algorithmus zu tun hat, aber ich kann nicht finden was falsch ist ...

Antwort

0

ich die Lösung für mein Problem gefunden, nachdem Lesen dieser Seiten (me gamedev sehr geholfen):

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

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

ich wieder tat wie so meine Kreuzung Gleichung und es richtig funktioniert:

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)); 
} 

Jetzt falsch meine Normalen sind, aber das ist nicht so groß ein Problem zu beheben.