带光线追踪的圆柱相交
Cylinder intersection with ray tracing
我是这里的新手,我正在尝试用 C 语言创建一个光线追踪程序,我正在研究圆柱体形状。
到目前为止我只有一半的圆柱体,我正在想办法得到另一半。
我检查了法线,这似乎不是问题所在。
我也尝试更改 none 路口的条件,但没有任何效果。
这是我到目前为止所做的:
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);
}
The rendered half cylinder
所以问题是:是否有解决方案可以用这个方程得到完整的圆柱体?
(谢谢)
我发现了我的错误,如果将来有人需要这个,我会尝试在这里描述它。
所以基本上,在渲染无限圆柱体时,我们会尝试获得最近的交点并渲染它。对于我们切割的有限圆柱体,它不起作用。
如果交点与圆柱体中心之间的距离大于圆柱体的长度,那么我们不考虑交点。即使在最近的交叉点(太高)处没有交叉点,它后面也有一个可能在圆柱体高度范围内。这是我们需要得到圆柱体另一侧的交点。
也许一些伪代码会有所帮助
// 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;
如果我可以尝试用一句话来恢复这个,我会说我们首先尝试获得最近的交点,但如果它不起作用,我们会尝试第二个(与球体不同)。
希望对以后的人有所帮助。
和平(并感谢回答的人)
我是这里的新手,我正在尝试用 C 语言创建一个光线追踪程序,我正在研究圆柱体形状。
到目前为止我只有一半的圆柱体,我正在想办法得到另一半。
我检查了法线,这似乎不是问题所在。
我也尝试更改 none 路口的条件,但没有任何效果。
这是我到目前为止所做的:
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);
}
The rendered half cylinder
所以问题是:是否有解决方案可以用这个方程得到完整的圆柱体? (谢谢)
我发现了我的错误,如果将来有人需要这个,我会尝试在这里描述它。 所以基本上,在渲染无限圆柱体时,我们会尝试获得最近的交点并渲染它。对于我们切割的有限圆柱体,它不起作用。 如果交点与圆柱体中心之间的距离大于圆柱体的长度,那么我们不考虑交点。即使在最近的交叉点(太高)处没有交叉点,它后面也有一个可能在圆柱体高度范围内。这是我们需要得到圆柱体另一侧的交点。
也许一些伪代码会有所帮助
// 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;
如果我可以尝试用一句话来恢复这个,我会说我们首先尝试获得最近的交点,但如果它不起作用,我们会尝试第二个(与球体不同)。
希望对以后的人有所帮助。 和平(并感谢回答的人)