## 3.5 Normals

A *surface normal* (or just *normal*) is a vector that is
perpendicular to a surface at a particular position. It can be defined as the
cross product of any two nonparallel vectors that are tangent to the surface
at a point. Although normals are superficially similar to vectors, it is
important to distinguish between the two of them: because normals are defined
in terms of their relationship to a particular surface, they behave differently
than vectors in some situations, particularly when applying transformations.
(That difference is discussed in Section 3.10.)

The implementations of `Normal3`s and `Vector3`s are very similar.
Like vectors, normals are represented by three components
`x`, `y`, and `z`; they can be added and subtracted to
compute new normals; and they can be scaled and
normalized. However, a normal cannot be
added to a point, and one cannot take the cross product of two normals.
Note that, in an unfortunate turn of terminology, normals are *not*
necessarily normalized.

In addition to the usual constructors (not included here), `Normal3`
allows conversion from `Vector3` values given an explicit typecast,
similarly to the other `Tuple2`- and `Tuple3`-based classes.

The `Dot()` and `AbsDot()` functions are also overloaded to compute
dot products between the various possible combinations of normals and
vectors. This code will not be included in the text here. We also will
not include implementations of all the various other `Normal3`
methods here, since they are similar to those for vectors.

One new operation to implement comes from the fact that it is often necessary to
flip a surface normal so it lies in the same hemisphere as a given
vector—for example, the surface normal that lies in the same hemisphere
as a ray leaving a surface is frequently needed. The `FaceForward()` utility
function encapsulates this small computation. (`pbrt` also provides
variants of this function for the other three combinations of
`Vector3`s and `Normal3`s as parameters.) Be careful when using
the other instances, though: when using the version that takes two
`Vector3`s, for example, ensure that the first parameter is the one
that should be returned (possibly flipped) and the second is the one to
test against. Reversing the two parameters will give unexpected results.