Elite on the BBC Micro

# Maths (Geometry): NORM (Cassette version)

```       Name: NORM                                              [View in context]
Type: Subroutine
Category: Maths (Geometry)
Summary: Normalise the three-coordinate vector in XX15
Deep dive: Tidying orthonormal vectors
Orientation vectors

We do this by dividing each of the three coordinates by the length of the
vector, which we can calculate using Pythagoras. Once normalised, 96 (&E0) is
used to represent a value of 1, and 96 with bit 7 set (&E0) is used to
represent -1. This enables us to represent fractional values of less than 1
using integers.

Arguments:

XX15                 The vector to normalise, with:

* The x-coordinate in XX15

* The y-coordinate in XX15+1

* The z-coordinate in XX15+2

Returns:

XX15                 The normalised vector

Q                    The length of the original XX15 vector

Other entry points:

NO1                  Contains an RTS

.NORM

LDA XX15               \ Fetch the x-coordinate into A

JSR SQUA               \ Set (A P) = A * A = x^2

STA R                  \ Set (R Q) = (A P) = x^2
LDA P
STA Q

LDA XX15+1             \ Fetch the y-coordinate into A

JSR SQUA               \ Set (A P) = A * A = y^2

STA T                  \ Set (T P) = (A P) = y^2

LDA P                  \ Set (R Q) = (R Q) + (T P) = x^2 + y^2
STA Q                  \ First, doing the low bytes, Q = Q + P

LDA T                  \ And then the high bytes, R = R + T
STA R

LDA XX15+2             \ Fetch the z-coordinate into A

JSR SQUA               \ Set (A P) = A * A = z^2

STA T                  \ Set (T P) = (A P) = z^2

LDA P                  \ Set (R Q) = (R Q) + (T P) = x^2 + y^2 + z^2
STA Q                  \ First, doing the low bytes, Q = Q + P

LDA T                  \ And then the high bytes, R = R + T
STA R

JSR LL5                \ We now have the following:
\
\ (R Q) = x^2 + y^2 + z^2
\
\ so we can call LL5 to use Pythagoras to get:
\
\ Q = SQRT(R Q)
\   = SQRT(x^2 + y^2 + z^2)
\
\ So Q now contains the length of the vector (x, y, z),
\ and we can normalise the vector by dividing each of
\ the coordinates by this value, which we do by calling
\ routine TIS2. TIS2 returns the divided figure, using
\ 96 to represent 1 and 96 with bit 7 set for -1

LDA XX15               \ Call TIS2 to divide the x-coordinate in XX15 by Q,
JSR TIS2               \ with 1 being represented by 96
STA XX15

LDA XX15+1             \ Call TIS2 to divide the y-coordinate in XX15+1 by Q,
JSR TIS2               \ with 1 being represented by 96
STA XX15+1

LDA XX15+2             \ Call TIS2 to divide the z-coordinate in XX15+2 by Q,
JSR TIS2               \ with 1 being represented by 96
STA XX15+2

.NO1

RTS                    \ Return from the subroutine
```