-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintersect.c
80 lines (72 loc) · 1.81 KB
/
intersect.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "raytracer.h"
/* intersect_sphere : intersect func for spheres */
hit_test intersect_sphere(ray r, object obj)
{
sphere s = obj.o.s;
hit_test result;
xyz A = xyz_sub(r.origin, s.center);
double B = xyz_dot(A, xyz_norm(r.dir));
double C = xyz_dot(A, A) - s.radius*s.radius;
double D = B*B - C;
double t = -B - sqrt(D);
ray newr = {r.origin, xyz_norm(r.dir)};
xyz loc = ray_position(newr,t);
xyz v = xyz_sub(loc, s.center);
xyz norm = xyz_norm(v);
if(D<=0 || t<=0)
result.miss = MISS;
else {
result.miss = HIT;
result.t = t;
result.hit_point = loc;
result.surf = s.surface_color(&obj, loc);
result.shine = s.shine;
result.surf_norm = norm;
}
return result;
}
/* intersect_poster : intersect func for posters */
hit_test intersect_poster(ray r, object obj)
{
poster p = obj.o.p;
hit_test result;
xyz n = xyz_expr(0, 0, -1);
double d = p.upper_left.z;
xyz rd = xyz_norm(r.dir);
double t = -(xyz_dot(r.origin, n) + d)/xyz_dot(rd, n);
ray newr = {r.origin, rd};
xyz loc = ray_position(newr,t);
xyz ul = p.upper_left;
if (t>0 &&
loc.x>=ul.x &&
loc.x<=(ul.x+p.w) &&
loc.y<=ul.y &&
loc.y>=(ul.y-p.h)) {
result.miss = HIT;
result.t = t;
result.hit_point = loc;
result.surf = p.surface_color(&obj, loc);
result.shine = p.shine;
result.surf_norm = n;
} else {
result.miss = MISS;
}
return result;
}
/* intersect: check if ray intersects with object, return hit_test */
hit_test intersect(ray r, object obj)
{
switch (obj.tag) {
case SPHERE :
return intersect_sphere(r,obj);
case POSTER :
return intersect_poster(r,obj);
default :
fprintf(stderr,"error(intersect):rogue tag\n");
exit(1);
}
}