4
#define _USE_MATH_DEFINES
17
Vector():x(0), y(0), z(0) {}
18
explicit Vector(float a):x(a), y(a), z(a) {}
19
explicit Vector(float a, float b, float c):x(a), y(b), z(c) {}
20
Vector(const Vector &v):x(v.x), y(v.y), z(v.z) {}
24
void set(float a) { x=y=z=a; }
25
void set(float a, float b, float c) { x=a; y=b; z=c; }
26
void set(const Vector &v) { x=v.x; y=v.y; z=v.z; }
29
float L = x*x + y*y + z*z;
30
if (L>0) return sqrt(L);
33
float lengthSquared() const { return x*x + y*y + z*z; }
36
// dotproduct, also as operator* below
37
float operator|(const Vector &v) const { return x*v.x + y*v.y + z*v.z; }
38
float dot(const Vector &v) const { return x*v.x + y*v.y + z*v.z; }
41
Vector operator^(const Vector &v) const { return Vector(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); }
42
Vector cross(const Vector &v) const { return Vector(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); }
46
float d = x*x + y*y + z*z;
49
x *= d, y *= d, z *= d;
55
float d = x*x + y*y + z*z;
58
const float dv = 1.f/d;
59
x *= dv, y *= dv, z *= dv;
63
float normLenSquared()
65
float d = x*x + y*y + z*z;
67
const float dv = 1.f/sqrtf(d);
68
x *= dv, y *= dv, z *= dv;
72
Vector& setLength(float L)
74
float d = x*x + y*y + z*z;
77
x *= d, y *= d, z *= d;
82
Vector operator+(const Vector &v) const { return Vector(x+v.x, y+v.y, z+v.z); }
83
Vector operator-(const Vector &v) const { return Vector(x-v.x, y-v.y, z-v.z); }
84
Vector operator-() const { return Vector(-x, -y, -z); }
85
Vector operator*(float s) const { return Vector(x*s, y*s, z*s); }
86
friend Vector operator*(float s, const Vector &v) { return Vector(v.x*s, v.y*s, v.z*s); }
87
float operator*(const Vector &v) const { return x*v.x + y*v.y + z*v.z; }
88
Vector operator/(float s) const { if (s!=0) s=1.f/s; return Vector(x*s, y*s, z*s); }
89
Vector& operator+=(const Vector &v) { x+=v.x; y+=v.y; z+=v.z; return *this; }
90
Vector& operator-=(const Vector &v) { x-=v.x; y-=v.y; z-=v.z; return *this; }
91
Vector& operator*=(float s) { x*=s; y*=s; z*=s; return *this; }
92
Vector& operator/=(float s) { if (s!=0) s=1.f/s; x*=s; y*=s; z*=s; return *this; }
93
Vector reflect(const Vector &n) const
95
const float k = 2.f * (x*n.x + y*n.y + z*n.z);
96
return Vector(x - k*n.x, y - k*n.y, z - k*n.z);
99
// componentwise mult.
100
Vector scale(const Vector &v) const { return Vector(v.x*x, v.y*y, v.z*z); }
103
float operator[](int i) const { return xyz[i]; }
104
float& operator[](int i) { return xyz[i]; }
107
struct { float x, y, z; };
115
Point3():x(0), y(0), z(0) {}
116
explicit Point3(float a):x(a), y(a), z(a) {}
117
explicit Point3(float a, float b, float c=0):x(a), y(b), z(c) {}
118
Point3(const Point3 &p):x(p.x), y(p.y), z(p.z) {}
119
Point3(const Vector &v):x(v.x), y(v.y), z(v.z) {}
120
void set(float ix, float iy, float iz=0) { x=ix; y=iy; z=iz; }
121
void set(const Point3 &p) { x=p.x; y=p.y; z=p.z; }
122
float length() const;
123
float lengthSquared() const;
124
float distance(const Point3 &a, const Point3 &b);
125
Point3 operator-() const { return Point3(-x, -y, -z); }
126
Point3& operator=(const Vector &v) { x=v.x; y=v.y; z=v.z; return *this; }
127
Point3& operator=(const Point3 &s) { x=s.x; y=s.y; z=s.z; return *this; }
128
Point3& operator+=(const Point3 &s) { x+=s.x; y+=s.y; z+=s.z; return *this;}
129
Point3& operator+=(const Vector &v) { x+=v.x; y+=v.y; z+=v.z; return *this;}
130
Point3& operator-=(const Point3 &s) { x-=s.x; y-=s.y; z-=s.z; return *this;}
131
Point3& operator*=(float s) { x*=s; y*=s; z*=s; return *this;}
132
Point3& operator/=(float s) { if (s!=0.f) s=1.f/s; x*=s; y*=s; z*=s; return *this;}
134
float operator[](int i) const { return xyz[i]; }
135
float& operator[](int i) { return xyz[i]; }
138
struct { float x, y, z; };
144
inline Point3 operator*(float f, const Point3 &p)
146
return Point3(f*p.x, f*p.y, f*p.z);
149
inline Point3 operator*(const Point3 &p, float f)
151
return Point3(p.x*f, p.y*f, p.z*f);
154
inline Point3 operator/(const Point3 &p, float f)
157
return Point3(p.x*f, p.y*f, p.z*f);
160
inline Vector operator-(const Point3 &a, const Point3 &b)
162
return Vector(a.x-b.x, a.y-b.y, a.z-b.z);
165
inline Point3 operator-(const Point3 &a, const Vector &b)
167
return Point3(a.x-b.x, a.y-b.y, a.z-b.z);
170
inline Point3 operator+(const Point3 &a, const Point3 &b)
172
return Point3(a.x+b.x, a.y+b.y, a.z+b.z);
175
inline Point3 operator+(const Point3 &a, const Vector &b)
177
return Point3(a.x+b.x, a.y+b.y, a.z+b.z);
180
inline Vector operator+(const Vector &a, const Point3 &b)
182
return Vector(a.x+b.x, a.y+b.y, a.z+b.z);
185
inline float Point3::length() const
187
return sqrt(x*x + y*y + z*z);
190
inline float Point3::lengthSquared() const
192
return x*x + y*y + z*z;
195
inline float distance(const Point3 &a, const Point3 &b)
197
const float i=a.x-b.x, j=a.y-b.y, k=a.z-b.z;
198
return sqrt(i*i + j*j + k*k);
201
inline Vector toVector(const Point3 &p)
203
return Vector(p.x, p.y, p.z);
209
Point2():x(0), y(0) {}
210
explicit Point2(float a):x(a), y(a) {}
211
explicit Point2(float a, float b):x(a), y(b) {}
212
Point2(const Point3 &p):x(p.x), y(p.y) {}
213
Point2(const Vector &v):x(v.x), y(v.y) {}
214
Point2(const Point2 &p):x(p.x), y(p.y) {}
216
void set(const Point2& p) { x = p.x; y = p.y; }
217
void set(float a, float b) { x = a; y = b; }
218
Point2 operator-() const { return Point2(-x, -y); }
219
Point2& operator=(const Point2 &p) { x=p.x; y=p.y; return *this; }
220
Point2& operator+=(const Point2 &p) { x+=p.x; y+=p.y; return *this; }
221
Point2& operator+=(const Point3 &p) { x+=p.x; y+=p.y; return *this; }
222
Point2& operator+=(const Vector &v) { x+=v.x; y+=v.y; return *this; }
223
Point2& operator-=(const Point2 &p) { x-=p.x; y-=p.y; return *this; }
224
Point2& operator-=(const Point3 &p) { x-=p.x; y-=p.y; return *this; }
225
Point2& operator-=(const Vector &v) { x-=v.x; y-=v.y; return *this; }
226
Point2& operator*=(float f) { x*=f; y*=f; return *this; }
227
friend Point2 operator*(float f, const Point2 &p) { return Point2(p.x*f, p.y*f); }
228
Point2& operator/=(float s) { if (s!=0.f) s=1.f/s; x*=s; y*=s; return *this;}
229
float operator[](int i) { return xy[i]; }
230
float operator[](int i) const { return xy[i]; }
233
struct { float x, y; };
238
inline Point2 operator+(const Point2 &a, const Point2 &b)
240
return Point2(a.x + b.x, a.y + b.y);
243
inline Point2 operator-(const Point2 &a, const Point2 &b)
245
return Point2(a.x - b.x, a.y - b.y);
248
// minimal homogeneous point class
252
HPoint():x(0), y(0), z(0), w(0) {}
253
explicit HPoint(float a):x(a), y(a), z(a), w(a) {}
254
explicit HPoint(float a, float b, float c, float d):x(a), y(b), z(c), w(d) {}
255
HPoint(const Point3 &p):x(p.x), y(p.y), z(p.z), w(1) {}
256
HPoint(const Vector &v):x(v.x), y(v.y), z(v.z), w(0) {}
257
HPoint(const HPoint &p):x(p.x), y(p.y), z(p.z), w(p.w) {}
259
void set(float a, float b, float c, float d) { x=a; y=b; z=c; w=d; }
260
HPoint operator-() const { return HPoint(-x, -y, -z, -w); }
261
HPoint& operator=(const HPoint &p) { x=p.x; y=p.y; z=p.z; w=p.w; return *this; }
262
HPoint& operator+=(const HPoint &p) { x+=p.x; y+=p.y; z+=p.z; w+=p.w; return *this; }
263
HPoint& operator+=(const Point3 &p) { x+=p.x; y+=p.y; z+=p.z; return *this; }
264
HPoint& operator+=(const Vector &v) { x+=v.x; y+=v.y; z+=v.z; return *this; }
265
HPoint& operator-=(const HPoint &p) { x-=p.x; y-=p.y; z-=p.z; w-=p.w; return *this; }
266
HPoint& operator-=(const Point3 &p) { x-=p.x; y-=p.y; z-=p.z; return *this; }
267
HPoint& operator-=(const Vector &v) { x-=v.x; y-=v.y; z-=v.z; return *this; }
268
HPoint& operator*=(float f) { x*=f; y*=f; z*=f; w*=f; return *this; }
269
friend HPoint operator*(float f, const HPoint &p) { return HPoint(p.x*f, p.y*f, p.z*f, p.w*f); }
270
float operator[](int i) { return xyzw[i]; }
271
float operator[](int i) const { return xyzw[i]; }
274
struct { float x, y, z, w; };
283
ray_t(const Point3& o, const Vector& d, const Vector& dx, const Vector& dy) : org(o), dir(d), dfx(dx), dfy(dy) {}
285
Vector dir, dfx, dfy;
288
// simple LC random number generator, good enough...
289
extern unsigned int _randomseed;
290
inline unsigned int irand()
292
_randomseed = 1664525L * _randomseed + 1013904223L;
295
inline float frand() { return irand()*(1.f/4294967286.f); }
296
inline float frandn() { return irand()*(1.f/2147483648.f)-1.f; }
298
void createCS(const Vector &N, Vector &u, Vector &v);
299
Vector RandomVectorSphere();
300
void shirleyDisc(float r1, float r2, float &du, float &dv);