BBC Micro Elite

# Calculating vertex coordinates

```Determining whether a ship's vertex is visible or hidden from us
----------------------------------------------------------------
References: LL9 (Part 6 of 11)
To understand the following, you'll probably want to have a look through the
deep dive on "Back-face culling", which describes how we can work out whether
or not a ship's face is visible.

As part of the back-face cull, we projected the vector [x y z] onto the
orientation vector space like this:

[x y z] projected onto sidev = [x y z] . sidev
[x y z] projected onto roofv = [x y z] . roofv
[x y z] projected onto nosev = [x y z] . nosev

We can express this exact same calculation in terms of matrix multiplication:

[ sidev ]   [ x ]
[ roofv ] . [ y ]
[ nosev ]   [ z ]

or, expanding it out fully:

[ sidev_x sidev_y sidev_z ]   [ x ]
projected [x y z] = [ roofv_x roofv_y roofv_z ] . [ y ]
[ nosev_x nosev_y nosev_z ]   [ z ]

This is just a different way of expressing the exact same equation as we used
in part 5 of LL9, just with a matrix instead of individual dot products.

Transposing the rotation matrix
-------------------------------
So the inverse matrix will map vectors in the orientation vector space back
into normal ship space. The inverse of a rotation matrix is its transpose, so
this is the calculation:

[ sidev_x roofv_x nosev_x ]   [ x ]
projected [x y z] = [ sidev_y roofv_y nosev_y ] . [ y ]
[ sidev_z roofv_z nosev_z ]   [ z ]

This takes a vector, which goes from the ship's centre to the vertex and is
expressed in terms of the ship's axes (i.e. its orientation vectors), and
instead expresses it in terms of our ship's axes (i.e. our orientation
vectors).

Given this new vector, we can add the vector from our ship to the other ship,
to get the vector from us to the vertex, expressed in our ship's coordinates:

[ sidev_x roofv_x nosev_x ]   [ x ]   [ x ]
vector to vertex = [ sidev_y roofv_y nosev_y ] . [ y ] + [ y ]
[ sidev_z roofv_z nosev_z ]   [ z ]   [ z ]

The code to calculate this equation takes up parts 6 and 7 of LL9. It's in two
parts because there are two small subroutines that have rudely inserted
themselves just before the big reveal. These are used by part 8 and don't play
a part in this calculation (except to make it harder to follow).

```