Skip to content

Commit 1d6edc6

Browse files
committed
add cone
1 parent c98f7e5 commit 1d6edc6

11 files changed

+115
-7
lines changed

include/debug.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void print_rgb(t_rgb color, bool newline);
2222
void print_sphere_conf(t_sphere_conf conf);
2323
void print_plane_conf(t_plane_conf conf);
2424
void print_cylinder_conf(t_cylinder_conf conf);
25+
void print_cone_conf(t_cone_conf conf);
2526
void print_material(t_material mat);
2627

2728
#endif

include/scene.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: kemizuki <[email protected]> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2023/12/16 06:43:04 by kemizuki #+# #+# */
9-
/* Updated: 2023/12/19 02:57:11 by kemizuki ### ########.fr */
9+
/* Updated: 2023/12/27 20:46:16 by smatsuo ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -74,7 +74,7 @@ typedef struct s_cylinder_conf
7474

7575
typedef struct s_cone_conf
7676
{
77-
t_vec3 center;
77+
t_vec3 apex;
7878
t_vec3 axis;
7979
double radius;
8080
double height;

include/tracer.h

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ bool hit_cylinder(t_object *cyl, t_ray ray, double tmin,
4848
t_hit_record *rec);
4949
bool hit_circle(t_object *circ, t_ray ray, double tmin,
5050
t_hit_record *rec);
51+
bool hit_cone(t_object *cone, t_ray ray, double tmin,
52+
t_hit_record *rec);
5153

5254
typedef struct s_quadratic
5355
{

scenes/cone_plane.rt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
A 0.2 255,255,255
2+
C 0,100,100 0,-0.707,-0.707 30
3+
L 200,200,200 0.8 255,255,255
4+
co 0,0,0 0,1,0 20 20 180,20,30
5+
pl 0,0,0 0,1,0 255,255,255

src/debug/print_config.c

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static void print_objects(t_list *objects, int indent)
4949
print_sphere_conf(*(t_sphere_conf *)obj->conf);
5050
else if (obj->type == OBJ_CYLINDER)
5151
print_cylinder_conf(*(t_cylinder_conf *)obj->conf);
52+
else if (obj->type == OBJ_CONE)
53+
print_cone_conf(*(t_cone_conf *)obj->conf);
5254
printf("%*s", indent + 2, "");
5355
print_material(obj->material);
5456
node = node->next;

src/debug/print_object.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: kemizuki <[email protected]> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2023/12/16 21:27:24 by kemizuki #+# #+# */
9-
/* Updated: 2023/12/26 07:07:20 by kemizuki ### ########.fr */
9+
/* Updated: 2023/12/27 22:40:31 by smatsuo ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -41,6 +41,17 @@ void print_cylinder_conf(t_cylinder_conf conf)
4141
print_rgb(conf.color, true);
4242
}
4343

44+
void print_cone_conf(t_cone_conf conf)
45+
{
46+
printf("Cone: apex=");
47+
print_vec(conf.apex, false);
48+
printf(", axis=");
49+
print_vec(conf.axis, false);
50+
printf(", diameter=%.1lf, height=%.1lf, color=",
51+
conf.radius * 2, conf.height);
52+
print_rgb(conf.color, true);
53+
}
54+
4455
void print_material(t_material mat)
4556
{
4657
printf("Material: diffuse=%.1lf, specular=%.1lf, "

src/scene/parse_line_each_object.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ t_cone_conf parse_cone(const char *line)
9191
if (array_size(split) != 6)
9292
exit_with_error(EXIT_PARSE_ERROR, "cone: invalid format");
9393
conf = (t_cone_conf){
94-
.center = parse_vec3(split[1]),
94+
.apex = parse_vec3(split[1]),
9595
.axis = parse_vec3(split[2]),
9696
.radius = parse_double(split[3]) / 2,
9797
.height = parse_double(split[4]),

src/scene/parse_line_object.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static void parse_object_conf(t_object *object, const char *line)
3838
init_object(object, OBJ_CYLINDER, sizeof(t_cylinder_conf));
3939
*(t_cylinder_conf *)object->conf = parse_cylinder(line);
4040
}
41-
else if (ft_strncmp(line, "cy", 2) == 0)
41+
else if (ft_strncmp(line, "co", 2) == 0)
4242
{
4343
init_object(object, OBJ_CONE, sizeof(t_cone_conf));
4444
*(t_cone_conf *)object->conf = parse_cone(line);

src/tracer/hit_cone.c

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* ************************************************************************** */
2+
/* */
3+
/* ::: :::::::: */
4+
/* hit_cone.c :+: :+: :+: */
5+
/* +:+ +:+ +:+ */
6+
/* By: smatsuo <[email protected]> +#+ +:+ +#+ */
7+
/* +#+#+#+#+#+ +#+ */
8+
/* Created: 2023/12/27 20:22:42 by smatsuo #+# #+# */
9+
/* Updated: 2023/12/27 22:40:01 by smatsuo ### ########.fr */
10+
/* */
11+
/* ************************************************************************** */
12+
13+
#include "tracer.h"
14+
15+
static bool set_rec(t_object *cone, t_ray ray, double t, t_hit_record *rec)
16+
{
17+
const t_cone_conf conf = *(t_cone_conf *)cone->conf;
18+
const t_vec3 pc = vec3_sub(ray_at(ray, t), conf.apex);
19+
20+
rec->t = t;
21+
rec->point = ray_at(ray, t);
22+
rec->normal = vec3_normalize(vec3_sub(pc, vec3_scale(conf.axis,
23+
vec3_dot(pc, pc) / vec3_dot(conf.axis, pc))));
24+
rec->material = cone->material;
25+
rec->object_color = conf.color;
26+
return (true);
27+
}
28+
29+
static bool is_hit_side(t_cone_conf conf, t_ray ray, double t)
30+
{
31+
const t_vec3 co = vec3_sub(ray_at(ray, t), conf.apex);
32+
33+
return (vec3_dot(co, conf.axis) > 0
34+
&& vec3_length(vec3_project(co, conf.axis)) <= conf.height);
35+
}
36+
37+
static bool hit_cone_cap(t_object *cone, t_ray ray, double tmin,
38+
t_hit_record *rec)
39+
{
40+
const t_cone_conf conf = *(t_cone_conf *)cone->conf;
41+
t_object circle;
42+
43+
circle = (t_object){
44+
.type = OBJ_CIRCLE,
45+
.conf = &(t_circle_conf){
46+
.center = vec3_add_scaled(conf.apex, conf.axis, conf.height),
47+
.normal = conf.axis,
48+
.radius = conf.radius,
49+
.color = conf.color},
50+
.material = cone->material};
51+
return (hit_circle(&circle, ray, tmin, rec));
52+
}
53+
54+
bool hit_cone(t_object *cone, t_ray ray, double tmin, t_hit_record *rec)
55+
{
56+
const t_cone_conf conf = *(t_cone_conf *)cone->conf;
57+
t_quadratic q;
58+
const double cos_2 = pow(cos(atan2(conf.radius, conf.height)), 2);
59+
const t_vec3 oc = vec3_sub(ray.origin, conf.apex);
60+
61+
q.a = pow(vec3_dot(ray.direction, conf.axis), 2)
62+
- vec3_length_squared(ray.direction) * cos_2;
63+
q.half_b = vec3_dot(ray.direction, conf.axis) * vec3_dot(oc, conf.axis)
64+
- vec3_dot(ray.direction, vec3_scale(oc, cos_2));
65+
q.c = pow(vec3_dot(oc, conf.axis), 2)
66+
- vec3_dot(oc, vec3_scale(oc, cos_2));
67+
solve_quadratic(&q);
68+
if (!q.solved)
69+
return (false);
70+
if (q.t1 > tmin && is_hit_side(conf, ray, q.t1))
71+
return (set_rec(cone, ray, q.t1, rec));
72+
if (hit_cone_cap(cone, ray, tmin, rec))
73+
return (true);
74+
if (q.t2 > tmin && is_hit_side(conf, ray, q.t2))
75+
return (set_rec(cone, ray, q.t2, rec));
76+
return (false);
77+
}

src/tracer/hit_func.c

+2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ t_hit_func get_hit_func(t_object *obj)
2020
return (hit_plane);
2121
else if (obj->type == OBJ_CYLINDER)
2222
return (hit_cylinder);
23+
else if (obj->type == OBJ_CONE)
24+
return (hit_cone);
2325
return (NULL);
2426
}

src/tracer/quadratic.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ void solve_quadratic(t_quadratic *q)
2424
if (discriminant < 0)
2525
return ;
2626
q->solved = true;
27-
q->t1 = (-q->half_b - sqrt(discriminant)) / q->a;
28-
q->t2 = (-q->half_b + sqrt(discriminant)) / q->a;
27+
if (q->a < 0)
28+
{
29+
q->t1 = (-q->half_b + sqrt(discriminant)) / q->a;
30+
q->t2 = (-q->half_b - sqrt(discriminant)) / q->a;
31+
}
32+
else
33+
{
34+
q->t1 = (-q->half_b - sqrt(discriminant)) / q->a;
35+
q->t2 = (-q->half_b + sqrt(discriminant)) / q->a;
36+
}
2937
}

0 commit comments

Comments
 (0)