-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeometry.h
157 lines (135 loc) · 3.49 KB
/
geometry.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
// for future improvements I could probably use a template for all the diff
// types of vectors it's possible to work with (combinations of floats, doubles,
// ints, etc)
struct Vec3f {
float x, y, z; // declare our three floats
Vec3f() { // default constructor
x = 0;
y = 0;
z = 0;
}
Vec3f(float a, float b, float c) { // user input
x = a;
y = b;
z = c;
}
float operator[](size_t index) {
if (index >= 3) {
cout << "Array index out of bound, exiting";
exit(0);
}
if (index == 0) {
return x;
} else if (index == 1) {
return y;
} else if (index == 2) {
return z;
} else {
std::cout << " Index out of bounds, exiting";
exit(0);
}
}
// operator overloading for printing out values of 3d float vectors
friend std::ostream &operator<<(std::ostream &os, const Vec3f &v) {
os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
return os;
}
// below simple operator overloadings for addition, subtraction,
// cross product, dot product, and various simple vector
// operations
Vec3f operator+(const Vec3f &v) const {
return Vec3f(x + v.x, y + v.y, z + v.z);
}
Vec3f operator+=(const Vec3f &v) {
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Vec3f operator-(const Vec3f &v) const {
return Vec3f(x - v.x, y - v.y, z - v.z);
}
Vec3f operator-=(const Vec3f &v) {
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
// for my purposes, * is scalar multiplication
Vec3f operator*(const float s) const { return Vec3f(s * x, s * y, s * z); }
Vec3f operator*=(const float s) {
x *= s;
y *= s;
z *= s;
return *this;
}
// dot product
float dot(const Vec3f &v) { return x * v.x + y * v.y + z * v.z; }
// cross product
Vec3f cross(const Vec3f &v) {
float i = y * v.z - z * v.y;
float j = z * v.x - x * v.z;
float k = x * v.y - y * v.x;
return Vec3f(i, j, k);
}
Vec3f normalize() {
float magnitude = sqrt(x * x + y * y + z * z);
return Vec3f(x / magnitude, y / magnitude, z / magnitude);
}
};
// now repeat for 2d float vectors
struct Vec2f {
float x, y; // declare our two floats
Vec2f() { // default constructor
x = 0;
y = 0;
}
Vec2f(float a, float b) { // user input
x = a;
y = b;
}
// operator overloading for printing out values of 2d vectors
friend std::ostream &operator<<(std::ostream &os, const Vec2f &v) {
os << "(" << v.x << ", " << v.y << ")";
return os;
}
};
struct Light {
Light(const Vec3f &p, const float &i) : position(p), intensity(i) {}
Vec3f position;
float intensity;
};
struct Material {
Material(const Vec3f &color) : diffuse_color(color) {}
Material() : diffuse_color() {}
Vec3f diffuse_color;
};
struct Sphere {
Vec3f center;
float radius;
Material material;
Sphere(const Vec3f &c, const float &r, const Material &m) : center(c), radius(r), material(m) {}
bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const {
Vec3f L = center - orig;
float tca = L.dot(dir);
float d2 = L.dot(L) - tca * tca;
if (d2 > radius * radius)
return false;
float thc = sqrtf(radius * radius - d2);
t0 = tca - thc;
float t1 = tca + thc;
if (t0 < 0)
t0 = t1;
if (t0 < 0)
return false;
return true;
}
};
#endif //__GEOMETRY_H__