-
Notifications
You must be signed in to change notification settings - Fork 0
/
sphere.cpp
34 lines (31 loc) · 1011 Bytes
/
sphere.cpp
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
#include <cmath>
#include <optional>
#include "sphere.h"
#include "util.h"
sphere::sphere(
const vec3f& center,
const float radius,
const material& surface_material
) : center(center), radius(radius), surface_material(surface_material) {}
std::optional<vec3f> sphere::ray_hit_point(
const vec3f& origin,
const vec3f& direction
) const {
// Solve:
// ||x - center|| = radius
// x = origin + t direction (0 <= t, ||direction|| = 1)
const vec3f origin_center{center - origin};
const float inner_prod{direction * origin_center};
const float discriminant{
square(radius) - origin_center.magnitude_sq() + square(inner_prod)
};
if (discriminant < 0.f) { return {}; }
const float sqrt_d{sqrtf(discriminant)};
if (const float t1{inner_prod - sqrt_d}; t1 >= 0.f) {
return origin + t1 * direction;
} else if (const float t2{inner_prod + sqrt_d}; t2 >= 0.f) {
return origin + t2 * direction;
} else {
return {};
}
}