Vectors and the vec3 Class
Introduction: Why Vectors Matter in Ray Tracing
In the previous lesson, you successfully generated your first image: a solid red square. To create that image, you used three separate integer variables for each pixel's color components: ired for red, igreen for green, and iblue for blue. This approach worked perfectly for a simple solid color, but let's think about what happens as our ray tracer becomes more sophisticated.
Imagine you're calculating the color of a pixel based on where a ray hits a sphere. You need to track the ray's starting position (three coordinates: x, y, z), the ray's direction (another three coordinates), the point where it hits the sphere (three more coordinates), and the surface normal at that point (yet another three coordinates). If you tried to manage all of these with separate variables, you'd quickly end up with code that looks like this:
This becomes unmanageable very quickly. You'd need to pass nine separate parameters to functions, perform operations on three variables at a time, and keep track of which x goes with which y and z. The code would be verbose, error-prone, and difficult to read.
This is where vectors come in. A vector is a mathematical object that naturally groups related values together. Instead of managing three separate variables, you work with a single entity that represents a point in 3D space, a direction, or even a color. In this lesson, you'll learn about the vec3 class, which will become one of your most important tools throughout this course.
The vec3 class provides a clean, organized way to work with three-component values. It handles all the common operations you need: adding vectors together, scaling them, measuring angles between them, and more. By the end of this lesson, you'll understand how vectors work, why they're essential for ray tracing, and how to use them in your code. You'll also discover something elegant: the same vec3 class that represents 3D positions and directions can also represent RGB colors, unifying your code in a beautiful way.
Understanding Vectors: More Than Just Three Numbers
Before we dive into code, let's build a solid understanding of what vectors actually are and why they're so useful in 3D graphics. A vector is fundamentally a mathematical object that has both magnitude (size) and direction. Think of it as an arrow in space: the arrow points in a specific direction, and it has a specific length.
In 3D graphics, we typically work with vectors in three-dimensional space, which means each vector has three components. We usually call these components x, y, and z. For example, a vector might be written as (3, 4, 5), where 3 is the x-component, 4 is the y-component, and 5 is the z-component. These three numbers completely describe the vector.
Vectors can represent different things depending on the context. One common use is to represent a position or point in 3D space. If you think of a 3D coordinate system with an origin at (0, 0, 0), then the vector (3, 4, 5) represents a point that's 3 units along the x-axis, 4 units along the y-axis, and 5 units along the z-axis from the origin.
Vectors can also represent directions. Imagine you're standing at the origin and you want to describe which way to walk. The vector (1, 0, 0) means "walk in the positive x direction." The vector (0, 1, 0) means "walk in the positive y direction." The vector (1, 1, 0) means "walk diagonally, equally in the x and y directions." The magnitude of the vector tells you how far to walk, and the direction tells you which way.
Here's a real-world analogy that might help. Imagine you're giving someone directions to walk from one location to another. You might say, "Walk 3 blocks east, 4 blocks north, and go up 5 floors." That instruction is essentially a vector: (3, 4, 5) where east is x, north is y, and up is z. The vector captures both the direction (northeast and upward) and the distance (the total length of the path).
In physics, vectors represent quantities like velocity and force. If a ball is moving with velocity (2, 3, 1), that means it's moving 2 units per second in the x direction, 3 units per second in the y direction, and 1 unit per second in the z direction. The vector completely describes the ball's motion.
You might wonder how vectors differ from simple arrays. After all, we could store three numbers in an array: double position[3] = {3, 4, 5};. The key difference is that vectors come with meaningful operations. When you add two vectors, you're performing a geometric operation that has real meaning: you're combining two displacements or directions. When you multiply a vector by a number (called a scalar), you're scaling its magnitude. These operations are built into the vector abstraction, making your code more expressive and less error-prone.
In ray tracing specifically, vectors are everywhere. The camera's position is a vector. The direction a ray travels is a vector. The point where a ray hits an object is a vector. The surface normal (the direction perpendicular to the surface) is a vector. Even colors, as you'll soon see, can be treated as vectors. Understanding vectors is absolutely fundamental to understanding ray tracing.


