-
Notifications
You must be signed in to change notification settings - Fork 0
/
vector.hpp
103 lines (82 loc) · 2.71 KB
/
vector.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
#include <cmath>
#include "triplet.hpp"
#include "utilities.hpp"
#ifndef VECTOR_HPP
#define VECTOR_HPP
class Vector : public Triplet {
public:
Vector() = default;
Vector(const Triplet& t) : Triplet(t){};
Vector(const double x, const double y, const double z) : Triplet(x, y, z){};
~Vector() = default;
double length() const {
return sqrt(lengthSquared());
}
double lengthSquared() const {
return x * x + y * y + z * z;
}
Vector normalize() const {
double len = length();
return Vector(x / len, y / len, z / len);
}
};
inline bool operator==(const Vector& lhs, const Vector& rhs) {
Vector normalizedLhs = lhs.normalize();
Vector normalizedRhs = rhs.normalize();
return normalizedLhs.getX() == normalizedRhs.getX() &&
normalizedLhs.getY() == normalizedRhs.getY() &&
normalizedLhs.getZ() == normalizedRhs.getZ();
}
inline double dot(const Vector& a, const Vector& b) {
return a.getX() * b.getX() + a.getY() * b.getY() + a.getZ() * b.getZ();
}
inline Vector cross(const Vector& a, const Vector& b) {
return Vector(a.getY() * b.getZ() - a.getZ() * b.getY(), a.getZ() * b.getX() - a.getX() * b.getZ(), a.getX() * b.getY() - a.getY() * b.getX());
}
inline double length(const Vector& v) {
return v.length();
}
inline Vector normalize(const Vector& v) {
return v.normalize();
}
inline Vector reflect(const Vector& v, const Vector& n) {
Vector vNorm = normalize(v);
Vector nNorm = normalize(n);
return vNorm - 2 * dot(vNorm, nNorm) * nNorm;
}
inline Vector refract(const Vector& uv, const Vector& n, const double etaiOverEtat) {
Vector uvNorm = normalize(uv);
Vector nNorm = normalize(n);
double cosTheta = fmin(dot(-1 * uvNorm, nNorm), 1.0);
Vector rOutPerp = etaiOverEtat * (uvNorm + cosTheta * nNorm);
Vector rOutParallel = -sqrt(fabs(1.0 - rOutPerp.lengthSquared())) * nNorm;
return rOutPerp + rOutParallel;
}
inline static Vector randomVector() {
return Vector(randomDouble(), randomDouble(), randomDouble());
}
inline static Vector randomVector(const double min, const double max) {
return Vector(randomDouble(min, max), randomDouble(min, max), randomDouble(min, max));
}
inline static Vector randomInUnitSphere() {
while (true) {
Vector p = randomVector(-1, 1);
if (length(p) >= 1) {
continue;
}
return p;
}
}
inline static Vector randomInUnitDisk() {
while (true) {
Vector p = Vector(randomDouble(-1, 1), randomDouble(-1, 1), 0);
if (length(p) >= 1) {
continue;
}
return p;
}
}
inline static Vector randomUnitVector() {
return normalize(randomInUnitSphere());
}
#endif // VECTOR_HPP