cylinder_surface.c
1 /* ************************************************************************** */ 2 /* */ 3 /* ::: :::::::: */ 4 /* cylinder_surface.c :+: :+: :+: */ 5 /* +:+ +:+ +:+ */ 6 /* By: salee2 <salee2@student.42seoul.kr> +#+ +:+ +#+ */ 7 /* +#+#+#+#+#+ +#+ */ 8 /* Created: 2023/05/24 20:21:56 by salee2 #+# #+# */ 9 /* Updated: 2023/05/24 20:21:57 by salee2 ### ########.fr */ 10 /* */ 11 /* ************************************************************************** */ 12 13 #include "include/minirt.h" 14 15 static t_coefficient get_coefficient(const t_cylinder *cylinder, t_ray *ray) 16 { 17 t_coefficient coef; 18 const t_vec3 w = sub(ray->origin, cylinder->base_center); 19 const double v_dot_h = dot(ray->dir, cylinder->normal); 20 const double w_dot_h = dot(w, cylinder->normal); 21 22 coef.a = mag_sq(ray->dir) - v_dot_h * v_dot_h; 23 coef.b = dot(ray->dir, w) - v_dot_h * w_dot_h; 24 coef.c = mag_sq(w) - w_dot_h * w_dot_h - cylinder->radius_sq; 25 return (coef); 26 } 27 28 static double ray_surface_intersection(const t_cylinder *cylinder, \ 29 t_ray *ray, t_hit *hit) 30 { 31 const t_coefficient coef = get_coefficient(cylinder, ray); 32 const double d = coef.b * coef.b - coef.a * coef.c; 33 double root; 34 double height; 35 t_vec3 cp; 36 37 if (d < 0.0) 38 return (INVALID_ROOT); 39 root = (-coef.b - sqrt(d)) / coef.a; 40 if (root < hit->t_min || hit->t_max < root) 41 { 42 root = (-coef.b + sqrt(d)) / coef.a; 43 if (root < hit->t_min || hit->t_max < root) 44 return (INVALID_ROOT); 45 } 46 cp = sub(ray_at(root, ray), cylinder->base_center); 47 height = dot(cp, cylinder->normal); 48 if (height < 0 || cylinder->height < height) 49 return (INVALID_ROOT); 50 return (root); 51 } 52 53 t_bool intersect_cylinder_surface(t_object *object, t_ray *ray, t_hit *hit) 54 { 55 const t_cylinder *cylinder = object->element; 56 const double root = ray_surface_intersection(cylinder, ray, hit); 57 t_vec3 cp; 58 59 if (root == INVALID_ROOT) 60 return (FALSE); 61 hit->t = root; 62 hit->t_max = hit->t; 63 hit->point = ray_at(hit->t, ray); 64 cp = sub(hit->point, cylinder->base_center); 65 hit->normal = norm(sub(cp, scl_mul(dot(cp, cylinder->normal), \ 66 cylinder->normal))); 67 if (dot(ray->dir, hit->normal) > 0.0) 68 hit->normal = scl_mul(-1, hit->normal); 69 hit->albedo = object->albedo; 70 return (TRUE); 71 }