Reputation: 31
I'm a newbie here and I'm trying to create a ray tracing program in C and I'm working on the cylinder shape.
So far I've got only half of the cylinder, I'm trying to find a way to get the other half.
I checked with the normals and it doesn't seem to be the problem.
I also tried to change the condition of none intersection but nothing is working.
Here is what I've done so far:
t_inter_point ft_cylinder_collision(t_ray ray, t_pack cylinder, int id)
{
t_inter_point inter_point;
t_delta delta;
t_ray new_ray;
t_vect c_to_o;
inter_point.hit = FALSE;
inter_point.id = id;
new_ray.origin = ray.origin;
cylinder.rot = normalize(cylinder.rot);
new_ray.direction = cross(ray.direction, cylinder.rot);
c_to_o = sub(ray.origin, cylinder.pos);
delta.a = dot(new_ray.direction, new_ray.direction);
delta.b = 2 * dot(new_ray.direction, cross(c_to_o, cylinder.rot));
delta.c = dot(cross(c_to_o, cylinder.rot), cross(c_to_o, cylinder.rot)) - pow(cylinder.diameter / 2, 2);
delta.delta = pow(delta.b, 2) - 4 * delta.c * delta.a;
if (delta.delta < 0)
return (inter_point);
inter_point.t1 = (-delta.b - sqrt(delta.delta)) / (2 * delta.a);
inter_point.t2 = (-delta.b + sqrt(delta.delta)) / (2 * delta.a);
if (inter_point.t2 < 0)
return (inter_point);
inter_point.t = (inter_point.t1 > 0 ? inter_point.t1 : inter_point.t2);
return (ft_find_edges(cylinder, ray, inter_point));
}
t_inter_point ft_find_edges(t_pack cylinder, t_ray ray,
t_inter_point inter_point)
{
double a;
ft_get_normal(ray, cylinder.pos, &inter_point);
if (get_norm(sub(inter_point.coord, cylinder.pos)) > cylinder.height)
return (inter_point);
a = dot(cylinder.rot, sub(inter_point.coord, cylinder.pos));
inter_point.normal = normalize(sub(inter_point.coord, add(cylinder.pos, ft_scale(cylinder.rot, a))));
inter_point.hit = TRUE;
return (inter_point);
}
So the question is : is there a solution to get the full cylinder with this equation ? (Thanks)
Upvotes: 1
Views: 3602
Reputation: 31
I found my error, and in case someone needs this int the future I'll try to describe it here. So basically, when rendering an infinite cylinder we try to get the closest intersection and we render it. For a finite cylinder that we cut, it doesn't work. If the distance between the intersection and the center of the cylinder is higher than the length of the cylinder, then we do not consider an intersection. Even though there is no intersection at the closest intersection (which is too high), there is one behind it which might be in the range of the height of the cylinder. And this is the intersection that we need to get the other side of our cylinder.
Maybe some pseudo code would help
// I assume you already found t1 and t2, the two intersections
if (t2 < 0) return ;
t = (t1 > 0 ? t1 : t2);
double max = sqrt(pow(cylinder.height / 2, 2) + pow(cylinder.radius, 2)); //pythagoras theorem
t_vect point = ray.origin + ray.direction * t;
t_vect len = point - cylinder.center;
if (norm(len) > max) // if t1 is too high we try with t2
t = t2;
t_vect point = ray.origin + ray.direction * t;
len = point - cylinder.center;
if (norm(len) > max) // if t2 is too high too then there is no intersection, else t2 is the intersection. And t2 is in the second half of the cylinder
return;
If I could try to resume this in a sentence, I'd say that we first try to get the closest intersection but if it doesn't work we try the second one (unlike spheres).
I hope it helps someone in the future. Peace (and thank you to the one who answered)
Upvotes: 2