/ miniRT / practice / miniRT_practice / cylinder_base.c
cylinder_base.c
 1  /* ************************************************************************** */
 2  /*                                                                            */
 3  /*                                                        :::      ::::::::   */
 4  /*   cylinder_base.c                                    :+:      :+:    :+:   */
 5  /*                                                    +:+ +:+         +:+     */
 6  /*   By: salee2 <salee2@student.42seoul.kr>         +#+  +:+       +#+        */
 7  /*                                                +#+#+#+#+#+   +#+           */
 8  /*   Created: 2023/05/24 20:21:52 by salee2            #+#    #+#             */
 9  /*   Updated: 2023/05/24 20:21:53 by salee2           ###   ########.fr       */
10  /*                                                                            */
11  /* ************************************************************************** */
12  
13  #include "include/minirt.h"
14  
15  static double	ray_disk_intersection(const t_cylinder *cylinder, t_ray *ray, \
16  t_hit *hit, t_point3 center)
17  {
18  	double	root;
19  	double	numerator;
20  	double	denominator;
21  
22  	denominator = dot(ray->dir, cylinder->normal);
23  	if (fabs(denominator) < EPSILON)
24  		return (INVALID_ROOT);
25  	numerator = dot(sub(center, ray->origin), cylinder->normal);
26  	root = numerator / denominator;
27  	if (root < hit->t_min || hit->t_max < root)
28  		return (INVALID_ROOT);
29  	if (mag_sq(sub(ray_at(root, ray), center)) > cylinder->radius_sq)
30  		return (INVALID_ROOT);
31  	return (root);
32  }
33  
34  t_bool	intersect_cylinder_base(t_object *object, t_ray *ray, t_hit *hit, \
35  enum e_component type)
36  {
37  	double				root;
38  	t_point3			center;
39  	const t_cylinder	*cylinder = object->element;
40  
41  	center = cylinder->top_center;
42  	if (type == BASE)
43  		center = cylinder->base_center;
44  	root = ray_disk_intersection(cylinder, ray, hit, center);
45  	if (root == INVALID_ROOT)
46  		return (FALSE);
47  	hit->t = root;
48  	hit->t_max = hit->t;
49  	hit->point = ray_at(hit->t, ray);
50  	hit->normal = cylinder->normal;
51  	if (dot(ray->dir, hit->normal) > 0.0)
52  		hit->normal = scl_mul(-1, hit->normal);
53  	hit->albedo = object->albedo;
54  	return (TRUE);
55  }