-
Notifications
You must be signed in to change notification settings - Fork 0
/
vec3d.h
135 lines (98 loc) · 3.06 KB
/
vec3d.h
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef VEC3D_H
#define VEC3D_H
#include <cmath>
#include <iostream>
#include "rtweekend.h"
using std::sqrt;
class Vec3D {
private:
double vector[3];
public:
Vec3D();
Vec3D(double e0, double e1, double e2);
double x() const;
double y() const;
double z() const;
Vec3D operator-() const;
double operator[](int i) const;
double &operator[](int i);
Vec3D &operator+=(const Vec3D &other);
Vec3D &operator*=(const double mult);
Vec3D &operator/=(const double t);
double length() const;
double lengthSquared() const;
bool nearZero() const;
static Vec3D random();
static Vec3D random(double min, double max);
};
// Type aliases for Vec3D
using Point3D = Vec3D; // 3D point
using Colour = Vec3D; // RGB color
// -------------------------- Utilities ---------------------------------
inline std::ostream &operator<<(std::ostream &out, const Vec3D &vec) {
return out << vec[0] << ' ' << vec[1] << ' ' << vec[2];
}
inline Vec3D operator+(const Vec3D &vec1, const Vec3D &vec2) {
return Vec3D{ vec1[0] + vec2[0], vec1[1] + vec2[1], vec1[2] + vec2[2] };
}
inline Vec3D operator-(const Vec3D &vec1, const Vec3D &vec2) {
return Vec3D{ vec1[0] - vec2[0], vec1[1] - vec2[1], vec1[2] - vec2[2] };
}
inline Vec3D operator*(const Vec3D &vec1, const Vec3D &vec2) {
return Vec3D{ vec1[0] * vec2[0], vec1[1] * vec2[1], vec1[2] * vec2[2] };
}
inline Vec3D operator*(double mult, const Vec3D &vec) {
return Vec3D{ mult * vec[0], mult * vec[1], mult * vec[2] };
}
inline Vec3D operator*(const Vec3D &vec, double mult) {
return mult * vec;
}
inline Vec3D operator/(Vec3D vec, double mult) {
return (1 / mult) * vec;
}
inline double dot(const Vec3D &vec1, const Vec3D &vec2) {
return vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2];
}
inline Vec3D cross(const Vec3D &vec1, const Vec3D &vec2) {
return Vec3D{ vec1[1] * vec2[2] - vec1[2] * vec2[1],
vec1[2] * vec2[0] - vec1[0] * vec2[2],
vec1[0] * vec2[1] - vec1[1] * vec2[0] };
}
inline Vec3D unitVector(Vec3D v) {
return v / v.length();
}
inline Vec3D randomInUnitSphere() {
while (true) {
auto p = Vec3D::random(-1, 1);
if (p.lengthSquared() >= 1) continue;
return p;
}
}
inline Vec3D randomUnitVector() {
return unitVector(randomInUnitSphere());
}
inline Vec3D randomInHemisphere(const Vec3D& normal) {
Vec3D inUnitSphere = randomInUnitSphere();
// Checks if in the same hemisphere as normal
if (dot(inUnitSphere, normal) > 0.0) {
return inUnitSphere;
}
return -inUnitSphere;
}
inline Vec3D reflect(const Vec3D& vec, const Vec3D& n) {
return vec - 2 * dot(vec, n) * n;
}
inline Vec3D refract(const Vec3D& R, const Vec3D& n, double etaiOverEtat) {
auto theta = fmin(dot(-R, n), 1.0);
Vec3D rOutPerpendicular = etaiOverEtat * (R + theta * n);
Vec3D rOutParallel = -sqrt(fabs(1.0 - rOutPerpendicular.lengthSquared())) * n;
return rOutPerpendicular + rOutParallel;
}
inline Vec3D randomInUnitDisk() {
while (true) {
auto p = Vec3D{ randomDouble(-1, 1), randomDouble(-1, 1), 0 };
if (p.lengthSquared() >= 1) continue;
return p;
}
}
#endif