-
Notifications
You must be signed in to change notification settings - Fork 0
/
raytracer.c
108 lines (89 loc) · 2.47 KB
/
raytracer.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdbool.h> /* Needed for boolean datatype */
int width = 256;
int height = 256;
/* The vector structure */
typedef struct{
float x, y, z;
}vector;
/* The sphere */
typedef struct{
vector pos;
float radius;
}sphere;
/* The ray */
typedef struct{
vector start;
vector dir;
}ray;
/* Subtract two vectors and return the resulting vector */
vector vectorSub(vector *v1, vector *v2){
vector result = {v1->x - v2->x, v1->y - v2->y, v1->z - v2->z };
return result;
}
/* Multiply two vectors and return the resulting scalar (dot product) */
float vectorDot(vector *v1, vector *v2){
return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
}
/* Check if the ray and sphere intersect */
bool intersectRaySphere(ray *r, sphere *s){
/* A = d.d, the vector dot product of the direction */
float A = vectorDot(&r->dir, &r->dir);
/* We need a vector representing the distance between the start of
* the ray and the position of the circle.
* This is the term (p0 - c)
*/
vector dist = vectorSub(&r->start, &s->pos);
/* 2d.(p0 - c) */
float B = 2 * vectorDot(&r->dir, &dist);
/* (p0 - c).(p0 - c) - r^2 */
float C = vectorDot(&dist, &dist) - (s->radius * s->radius);
/* Solving the discriminant */
float discr = B * B - 4 * A * C;
/* If the discriminant is negative, there are no real roots.
* Return false in that case as the ray misses the sphere.
* Return true in all other cases (can be one or two intersections)
*/
if(discr < 0)
return false;
else
return true;
}
int main(){
printf("P6\n"); // Define what type of BM we are going to do.
printf("%d %d\n255\n", width, height); // Give information about height and color depth.
/* Our ray and a sphere */
sphere s;
/* Position the sphere */
s.pos.x = 128;
s.pos.y = 128;
s.pos.z = 20;
ray r;
/* Sphere radius */
s.radius = 30;
/* Direction of the ray */
r.dir.x = 0;
r.dir.y = 0;
r.dir.z = 1;
/* Start position of the ray, z coordinate */
r.start.z = 0;
//Don't know how to do def within for loop, yet...
int y;
int x;
// Iterate over every pixel
for(y= 0; y < width; ++y){
/* Set the y-coordinate of the start position of the ray */
r.start.y = y;
for(x = 0; x < height; ++x){
/* Set the x-coordinate of the start position of the ray */
r.start.x = x;
/* Check if the ray intersects with the shpere */
if(intersectRaySphere(&r, &s)){
printf("%c%c%c", 255, 0, 0);
}
else{
printf("%c%c%c", 0, 0, 0);
}
}
}
}