-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsphere.hpp
117 lines (95 loc) · 3.32 KB
/
sphere.hpp
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
115
116
117
#pragma once
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#pragma region
#include "geometry.hpp"
#include "hittable.hpp"
#pragma endregion
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
#pragma region
#define EPSILON_SPHERE 1e-4
#pragma endregion
//-----------------------------------------------------------------------------
// Declarations and Definitions
//-----------------------------------------------------------------------------
namespace pathtracing
{
//-------------------------------------------------------------------------
// Declarations and Definitions: Sphere
//-------------------------------------------------------------------------
struct Sphere final : public Hittable
{
//---------------------------------------------------------------------
// Constructors and Destructors
//---------------------------------------------------------------------
explicit Sphere(double r, Vector3 p, Vector3 e, Vector3 f,
Reflection_t reflection_t) noexcept
: m_r(r), m_p(std::move(p)), Hittable(e, f, reflection_t) {}
Sphere(const Sphere &sphere) noexcept = default;
Sphere(Sphere &&sphere) noexcept = default;
~Sphere() = default;
//---------------------------------------------------------------------
// Assignment Operators
//---------------------------------------------------------------------
Sphere &operator=(const Sphere &sphere) = default;
Sphere &operator=(Sphere &&sphere) = default;
//---------------------------------------------------------------------
// Member Methods
//---------------------------------------------------------------------
bool Intersect(const Ray &ray) const
{
// (o + t*d - p) . (o + t*d - p) - r*r = 0
// <=> (d . d) * t^2 + 2 * d . (o - p) * t + (o - p) . (o - p) - r*r = 0
//
// Discriminant check
// (2 * d . (o - p))^2 - 4 * (d . d) * ((o - p) . (o - p) - r*r) <? 0
// <=> (d . (o - p))^2 - (d . d) * ((o - p) . (o - p) - r*r) <? 0
// <=> (d . op)^2 - 1 * (op . op - r*r) <? 0
// <=> b^2 - (op . op) + r*r <? 0
// <=> D <? 0
//
// Solutions
// t = (- 2 * d . (o - p) +- 2 * sqrt(D)) / (2 * (d . d))
// <=> t = dop +- sqrt(D)
const Vector3 op = m_p - ray.m_o;
const double dop = ray.m_d.Dot(op);
const double D = dop * dop - op.Dot(op) + m_r * m_r;
if (D < 0)
{
return false;
}
const double sqrtD = sqrt(D);
const double tmin = dop - sqrtD;
if (ray.m_tmin < tmin && tmin < ray.m_tmax)
{
ray.m_tmax = tmin;
return true;
}
const double tmax = dop + sqrtD;
if (ray.m_tmin < tmax && tmax < ray.m_tmax)
{
ray.m_tmax = tmax;
return true;
}
return false;
}
Vector3 get_intersection_normal(const Ray &ray) const
{
return Normalize(ray(ray.m_tmax) - m_p);
}
Vector3 get_color(Vector3 intersect_point) const {
return Vector3();
}
//---------------------------------------------------------------------
// Member Variables
//---------------------------------------------------------------------
double m_r;
Vector3 m_p; // position
// Vector3 m_e; // emission
// Vector3 m_f; // reflection
// Reflection_t m_reflection_t;
};
} // namespace pathtracing