Scale With Dots

In which you learn how scaling can be expressed in terms of dot products.

GPUs can calculate dot products very quickly. For this reason, graphics developers often express transformations in terms of dot products instead of the forms you read about earlier. The dot product forms won't be nearly so straightforward as the earlier forms, and you will question their worth. That's okay. The payoff will be a comprehensive and speedy system for representing transformations.

Scaling vector \(\mathbf{p}\) was earlier accomplished by multiplying it component-wise with a vector of \(\mathbf{factors}\). This produced a new scaled vector \(\mathbf{p'}\):

$$ \mathbf{p'} = \mathbf{factors} \times \mathbf{p} $$

There are many ways to write this. Perhaps you prefer this notation in which the vectors are exploded?

$$ \begin{bmatrix} p'_x \\ p'_y \\ p'_z \end{bmatrix} = \begin{bmatrix} \textrm{factors}_x \\ \textrm{factors}_y \\ \textrm{factors}_z \end{bmatrix} \times \begin{bmatrix}p_x \\ p_y \\ p_z \end{bmatrix} $$

Recasting this as a dot product takes some imagination. Since the dot product produces a scalar, focus first on computing the scaled coordinates separately. Using scalar multiplication, you'd write something like this:

$$ \begin{aligned} p'_x &= \textrm{factors}_x \times p_x \\ p'_y &= \textrm{factors}_y \times p_y \\ p'_z &= \textrm{factors}_z \times p_z \end{aligned} $$

Using dot products, your equations would have the following form:

$$ \begin{aligned} p'_x &= \mathbf{?} \cdot \mathbf{?} \\ p'_y &= \mathbf{?} \cdot \mathbf{?} \\ p'_z &= \mathbf{?} \cdot \mathbf{?} \end{aligned} $$

You need to replace each \(\mathbf{?}\) with a vector. In the scalar multiplication form, the second operand is always a component of \(\mathbf{p}\). Therefore you might as well drop \(\mathbf{p}\) in as the second operand:

$$ \begin{aligned} p'_x &= \mathbf{?} \cdot \mathbf{p} \\ p'_y &= \mathbf{?} \cdot \mathbf{p} \\ p'_z &= \mathbf{?} \cdot \mathbf{p} \end{aligned} $$

Since the scaled components are likely going to be different, the three remaining vectors are generally going to be different too. You decide to give them unique names:

$$ \begin{aligned} p'_x &= \mathbf{a} \cdot \mathbf{p} \\ p'_y &= \mathbf{b} \cdot \mathbf{p} \\ p'_z &= \mathbf{c} \cdot \mathbf{p} \end{aligned} $$

With some rewriting, you can figure out what these vectors should be in order to produce the expected scale transformation. Start by exploding the vectors:

$$ \begin{aligned} p'_x &= \begin{bmatrix}a_x&a_y&a_z\end{bmatrix} \cdot \begin{bmatrix}p_x&p_y&p_z\end{bmatrix} \\ p'_y &= \begin{bmatrix}b_x&b_y&b_z\end{bmatrix} \cdot \begin{bmatrix}p_x&p_y&p_z\end{bmatrix} \\ p'_z &= \begin{bmatrix}c_x&c_y&c_z\end{bmatrix} \cdot \begin{bmatrix}p_x&p_y&p_z\end{bmatrix} \\ \end{aligned} $$

Then expand the dot products:

$$ \begin{aligned} p'_x &= a_x \times p_x + a_y \times p_y + a_z \times p_z \\ p'_y &= b_x \times p_x + b_y \times p_y + b_z \times p_z \\ p'_z &= c_x \times p_x + c_y \times p_y + c_z \times p_z \\ \end{aligned} $$

Recall that you want \(p'_x = \textrm{factors}_x \times p_x\). What does that tell you about \(\mathbf{a}\)? The first component must be \(\textrm{factors}_x\) and the other two must be 0. Substitute these back in to your equations:

$$ \begin{aligned} p'_x &= \textrm{factors}_x \times p_x + 0 \times p_y + 0 \times p_z \\ &= \begin{bmatrix}\textrm{factors}_x&0&0\end{bmatrix} \cdot \begin{bmatrix}p_x & p_y & p_z\end{bmatrix} \\ &= \begin{bmatrix}\textrm{factors}_x&0&0\end{bmatrix} \cdot \mathbf{p} \\ \end{aligned} $$

The y- and z-components are constructed similarly. In each case, two zeroes are used to cancel out the unwanted parts of \(\mathbf{p}\). Altogether, your scale transformation looks like this when written as dot products:

$$ \begin{aligned} p'_x &= \begin{bmatrix}\textrm{factors}_x & 0 & 0\end{bmatrix} \cdot \mathbf{p} \\ p'_y &= \begin{bmatrix}0 & \textrm{factors}_y & 0\end{bmatrix} \cdot \mathbf{p} \\ p'_z &= \begin{bmatrix}0 & 0 & \textrm{factors}_z\end{bmatrix} \cdot \mathbf{p} \\ \end{aligned} $$

You've recast scale. Can you do the same with rotate?