Skip to content

Commit

Permalink
vec3: update text to match
Browse files Browse the repository at this point in the history
Resolves #153
Resolves #156
Resolves #215
  • Loading branch information
hollasch committed Oct 21, 2019
1 parent f93ba22 commit 444685e
Showing 1 changed file with 62 additions and 108 deletions.
170 changes: 62 additions & 108 deletions books/RayTracingInOneWeekend.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
video game renderers are written in C++. Note that I avoid most “modern features” of C++, but
inheritance and operator overloading are too useful for ray tracers to pass on. I do not provide the
code online, but the code is real and I show all of it except for a few straightforward operators in
the vec3 class. I am a big believer in typing in code to learn it, but when code is available I use
it, so I only practice what I preach when the code is not available. So don’t ask!
the `vec3` class. I am a big believer in typing in code to learn it, but when code is available I
use it, so I only practice what I preach when the code is not available. So don’t ask!

I have left that last part in because it is funny what a 180 I have done. Several readers ended up
with subtle errors that were helped when we compared code. So please do type in the code, but if you
Expand Down Expand Up @@ -155,146 +155,100 @@
have a good point, but we’re going to always take the “less code” route when not obviously wrong.

<div class='together'>
Here’s the top part of my vec3 class:
Here’s the top part of my `vec3` class:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
#include <iostream>
#include <math.h>
#include <stdlib.h>

class vec3 {
public:
vec3() {}
vec3(double e0, double e1, double e2) { e[0] = e0; e[1] = e1; e[2] = e2; }
inline double x() const { return e[0]; }
inline double y() const { return e[1]; }
inline double z() const { return e[2]; }
inline double r() const { return e[0]; }
inline double g() const { return e[1]; }
inline double b() const { return e[2]; }

inline const vec3& operator+() const { return *this; }
inline vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
inline double operator[](int i) const { return e[i]; }
inline double& operator[](int i) { return e[i]; }

inline vec3& operator+=(const vec3 &v2);
inline vec3& operator-=(const vec3 &v2);
inline vec3& operator*=(const vec3 &v2);
inline vec3& operator/=(const vec3 &v2);
inline vec3& operator*=(const double t);
inline vec3& operator/=(const double t);

inline double length() const { return sqrt(e[0]*e[0] + e[1]*e[1] + e[2]*e[2]); }
inline double squared_length() const { return e[0]*e[0] + e[1]*e[1] + e[2]*e[2]; }
inline void make_unit_vector();

double e[3];
public:
vec3() : e{0,0,0} {}
vec3(double e0, double e1, double e2) : e{e0, e1, e2} {}

double x() const { return e[0]; }
double y() const { return e[1]; }
double z() const { return e[2]; }

vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
double operator[](int i) const { return e[i]; }
double& operator[](int i) { return e[i]; }

vec3& vec3::operator+=(const vec3 &v) {
e[0] += v.e[0];
e[1] += v.e[1];
e[2] += v.e[2];
return *this;
}

vec3& vec3::operator*=(const double t) {
e[0] *= t;
e[1] *= t;
e[2] *= t;
return *this;
}

vec3& vec3::operator/=(const double t) {
return *this *= 1/t;
}

double length() const {
return sqrt(squared_length());
}

double squared_length() const {
return e[0]*e[0] + e[1]*e[1] + e[2]*e[2];
}

double e[3];
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</div>

We use `double` here, but some ray tracers use `float`. Either one is fine -- follow your own
tastes. Everything is in the header file, and later on in the file are lots of vector operations:
tastes. The second part of the header file contains vector utility functions:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
inline std::istream& operator>>(std::istream &is, vec3 &t) {
is >> t.e[0] >> t.e[1] >> t.e[2];
return is;
}
// vec3 Utility Functions

inline std::ostream& operator<<(std::ostream &os, const vec3 &t) {
os << t.e[0] << " " << t.e[1] << " " << t.e[2];
return os;
inline std::ostream& operator<<(std::ostream &out, const vec3 &v) {
return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2];
}

inline void vec3::make_unit_vector() {
auto k = 1.0 / sqrt(e[0]*e[0] + e[1]*e[1] + e[2]*e[2]);
e[0] *= k; e[1] *= k; e[2] *= k;
inline vec3 operator+(const vec3 &u, const vec3 &v) {
return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]);
}

inline vec3 operator+(const vec3 &v1, const vec3 &v2) {
return vec3(v1.e[0] + v2.e[0], v1.e[1] + v2.e[1], v1.e[2] + v2.e[2]);
inline vec3 operator-(const vec3 &u, const vec3 &v) {
return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]);
}

inline vec3 operator-(const vec3 &v1, const vec3 &v2) {
return vec3(v1.e[0] - v2.e[0], v1.e[1] - v2.e[1], v1.e[2] - v2.e[2]);
}

inline vec3 operator*(const vec3 &v1, const vec3 &v2) {
return vec3(v1.e[0] * v2.e[0], v1.e[1] * v2.e[1], v1.e[2] * v2.e[2]);
inline vec3 operator*(const vec3 &u, const vec3 &v) {
return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]);
}

inline vec3 operator*(double t, const vec3 &v) {
return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}

inline vec3 operator*(const vec3 &v, double t) {
return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}

inline vec3 operator/(const vec3 &v1, const vec3 &v2) {
return vec3(v1.e[0] / v2.e[0], v1.e[1] / v2.e[1], v1.e[2] / v2.e[2]);
return t * v;
}

inline vec3 operator/(vec3 v, double t) {
return vec3(v.e[0]/t, v.e[1]/t, v.e[2]/t);
}

inline double dot(const vec3 &v1, const vec3 &v2) {
return v1.e[0]*v2.e[0]
+ v1.e[1]*v2.e[1]
+ v1.e[2]*v2.e[2];
}

inline vec3 cross(const vec3 &v1, const vec3 &v2) {
return vec3(v1.e[1] * v2.e[2] - v1.e[2] * v2.e[1],
v1.e[2] * v2.e[0] - v1.e[0] * v2.e[2],
v1.e[0] * v2.e[1] - v1.e[1] * v2.e[0]);
}

inline vec3& vec3::operator+=(const vec3 &v) {
e[0] += v.e[0];
e[1] += v.e[1];
e[2] += v.e[2];
return *this;
return (1/t) * v;
}

inline vec3& vec3::operator-=(const vec3& v) {
e[0] -= v.e[0];
e[1] -= v.e[1];
e[2] -= v.e[2];
return *this;
inline double dot(const vec3 &u, const vec3 &v) {
return u.e[0] * v.e[0]
+ u.e[1] * v.e[1]
+ u.e[2] * v.e[2];
}

inline vec3& vec3::operator*=(const vec3 &v) {
e[0] *= v.e[0];
e[1] *= v.e[1];
e[2] *= v.e[2];
return *this;
}

inline vec3& vec3::operator*=(const double t) {
e[0] *= t;
e[1] *= t;
e[2] *= t;
return *this;
}

inline vec3& vec3::operator/=(const vec3 &v) {
e[0] /= v.e[0];
e[1] /= v.e[1];
e[2] /= v.e[2];
return *this;
}

inline vec3& vec3::operator/=(const double t) {
auto k = 1.0/t;

e[0] *= k;
e[1] *= k;
e[2] *= k;
return *this;
inline vec3 cross(const vec3 &u, const vec3 &v) {
return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1],
u.e[2] * v.e[0] - u.e[0] * v.e[2],
u.e[0] * v.e[1] - u.e[1] * v.e[0]);
}

inline vec3 unit_vector(vec3 v) {
Expand Down

0 comments on commit 444685e

Please sign in to comment.