-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsphere.c
More file actions
114 lines (94 loc) · 2.95 KB
/
sphere.c
File metadata and controls
114 lines (94 loc) · 2.95 KB
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
109
110
111
112
113
114
//
// sphere.c
// raycast
//
// Created by Liam Westby on 2/6/13.
// Functions pertaining to the sphere shape.
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "vector.h"
#include "sphere.h"
/* Read in a scene file and convert the shapes into a struct. Currently returns hardcoded values.
*
* file_path: The path to the file to be read.
*
* Return: An array of pointers to sphere structs.
*/
sphere** read_spheres(char *file_path) {
sphere** objects = (sphere**)malloc(sizeof(sphere*)*6);
for (int i = 0; i < 6; i++) {
objects[i] = (sphere*)malloc(sizeof(sphere));
objects[i]->center = (float*)malloc(sizeof(float)*3);
}
//Red sphere
v_init(-0.3, 0.2, -0.6, objects[0]->center);
objects[0]->radius = 0.2;
objects[0]->color.r = 255;
objects[0]->color.g = 0;
objects[0]->color.b = 0;
//Orange sphere
v_init(0.15, -0.2, -0.6, objects[1]->center);
objects[1]->radius = 0.15;
objects[1]->color.r = 255;
objects[1]->color.g = 165;
objects[1]->color.b = 0;
//Yellow sphere
v_init(0.1, 0.175, -0.15, objects[2]->center);
objects[2]->radius = 0.05;
objects[2]->color.r = 255;
objects[2]->color.g = 255;
objects[2]->color.b = 0;
//Green sphere
v_init(0.0, 0.13, -0.3, objects[3]->center);
objects[3]->radius = 0.025;
objects[3]->color.r = 0;
objects[3]->color.g = 255;
objects[3]->color.b = 0;
//Blue sphere
v_init(0.3, -0.2, -0.2, objects[4]->center);
objects[4]->radius = 0.125;
objects[4]->color.r = 0;
objects[4]->color.g = 0;
objects[4]->color.b = 255;
//Magenta sphere
v_init(-0.2, 0.0, -0.4, objects[5]->center);
objects[5]->radius = 0.06;
objects[5]->color.r = 255;
objects[5]->color.g = 0;
objects[5]->color.b = 255;
return objects;
}
/* Determine whether the given vector created by the point and direction intersects at any point on the given sphere.
*
* to_check: The sphere to check for intersection.
* origin: The origin of the ray.
* direction: unit vector representing the direction of the ray.
*
* Return: The shortest distance to intersection if it happens, or INFINITY if it does not.
*/
float sphere_intersect(sphere *to_check, float *origin, float *direction) {
float a = v_dot(direction, direction);
float *temp = (float*)malloc(sizeof(float)*3);
v_sub(origin, to_check->center, temp);
v_scale(temp, 2, temp);
float b = v_dot(temp, direction);
v_sub(origin, to_check->center, temp);
float c = v_dot(temp, temp);
c -= to_check->radius * to_check->radius;
float discriminant = b*b - 4*a*c;
if (discriminant < 0) {
return INFINITY;
}
float t1 = (-b + sqrtf(b*b - 4*a*c))/2*a;
float t2 = (-b - sqrtf(b*b - 4*a*c))/2*a;
if (t1 > 0 && t2 > 0) {
return t1 < t2 ? t1 : t2;
}
if (t1 > 0) return t1;
if (t2 > 0) return t2;
else {
return INFINITY;
}
}