-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sphere.cpp
executable file
·78 lines (64 loc) · 1.53 KB
/
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
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
#include "Sphere.h"
#include "Ray.h"
#include "Console.h"
Sphere::Sphere()
{
}
Sphere::~Sphere()
{
}
void
Sphere::renderGL()
{
glColor3f(1, 1, 1);
glPushMatrix();
glTranslatef(m_center.x, m_center.y, m_center.z);
glutWireSphere(m_radius, 20, 20);
glPopMatrix();
}
Vector3
Sphere::getPoint() const
{
return m_center;
}
std::vector<Vector3>
Sphere::getVertices() const
{
std::vector<Vector3> vertices;
vertices.push_back(m_center + Vector3(1,1,1)*radius());
vertices.push_back(m_center - Vector3(1,1,1)*radius());
return vertices;
}
bool
Sphere::intersect(HitInfo& result, const Ray& ray, float tMin, float tMax)
{
const Vector3 toO = ray.o - m_center;
const float a = ray.d.length2();
const float b = dot(2*ray.d, toO);
const float c = toO.length2() - m_radius*m_radius;
const float discrim = b*b-4.0f*a*c;
if (discrim < 0) return false; // quadratic equation would yield imaginary numbers
const float sqrt_discrim = sqrt(discrim);
// solve the quadratic equation
const float t[2] = {(-b-sqrt_discrim)/(2.0f*a), (-b+sqrt_discrim)/(2.0f*a)};
// since we know that discrim >= 0, t[0] < t{1]
// return the t closest to us that is within range
if ((t[0] > tMin+epsilon) && (t[0] < tMax))
{
result.t = t[0];
}
else if((t[1] > tMin+epsilon) && (t[1] < tMax))
{
result.t = t[1];
}
else
{
// neither of the solutions are in the required range
return false;
}
result.P = ray.o + result.t*ray.d;
result.N = (result.P-m_center);
result.N.normalize();
result.material = this->m_material;
return true;
}