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