Fix cylinder rendering
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 28 Nov 2024 22:03:25 +0000 (23:03 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 28 Nov 2024 22:03:25 +0000 (23:03 +0100)
I thought that the ray forms and acute angle with a vector from
point of entry to cylinder center, but that was not true.
Instead the projections to the plane orthogonal the rotational axis have
this property. So in this commit I implement the test for it.

src/scene.c

index 19466930466d20f2fdf34d611de28e79a3dfbc46..42571c2e24b2d3ea6786ee45ba9689abfc146f7a 100644 (file)
@@ -148,12 +148,12 @@ double    get_intersection_arg_cylinder_around
        args = solve_quadratic(vec_scalar_mul(v, v), 2 * vec_scalar_mul(v, u),
                        vec_scalar_mul(u, u) - cylinder->radius * cylinder->radius);
        intersect = ray_point(ray, args.first);
-       if (fabs(vec_scalar_mul(cylinder->rot_axis, intersect)) < cylinder->height / 2
-               && vec_scalar_mul(ray->direction, vec_diff(cylinder->center, intersect)) > 0)
+       if (fabs(vec_scalar_mul(cylinder->rot_axis, vec_diff(intersect, cylinder->center))) < cylinder->height / 2
+               && vec_scalar_mul(vec_vec_mul(cylinder->rot_axis, ray->direction), vec_vec_mul(cylinder->rot_axis, vec_diff(cylinder->center, intersect))) > 0)
                return (args.first);
        intersect = ray_point(ray, args.second);
-       if (fabs(vec_scalar_mul(cylinder->rot_axis, intersect)) < cylinder->height / 2
-               && vec_scalar_mul(ray->direction, vec_diff(cylinder->center, intersect)) > 0)
+       if (fabs(vec_scalar_mul(cylinder->rot_axis, vec_diff(intersect, cylinder->center))) < cylinder->height / 2
+               && vec_scalar_mul(vec_vec_mul(cylinder->rot_axis, ray->direction), vec_vec_mul(cylinder->rot_axis, vec_diff(cylinder->center, intersect))) > 0)
                return (args.second);
        return (NAN);
 }
@@ -164,7 +164,7 @@ double      get_intersection_arg_cylinder
        double  res;
 
        res = get_intersection_arg_cylinder_base(ray, cylinder);
-       if (res == NAN)
+       if (isnan(res))
                res = get_intersection_arg_cylinder_around(ray, cylinder);
        return (res);
 }