scruss wrote: ↑Sat Aug 03, 2019 1:19 am
I'm still all at sea trying to work out the subscripting for a simple 2d rotation matrix. BBC BASIC needs it dimensioned precisely, where ANSI BASIC tends to do it for you
It's complicated by there often being a choice of two alternatives: having the rotation matrix as the second term in the dot product, or swapping the row and column indices in the object array and having the (transposed) rotation matrix as the first term in the dot product. They give identical results but occasionally one has an advantage over the other; for example if you want to sort the objects according to their Z-coordinates (typically when plotting in 3D when you want to draw the furthest objects first) that may impose a specific row-column order.
That probably makes things even less clear, so I would suggest you study the example program
torus2d.bbc supplied with all editions of
BBC BASIC for SDL 2.0. Although BBC BASIC supports accelerated 3D graphics using the GPU to do the heavy lifting, this program illustrates how you can leverage the dot-product (and the sort library) to achieve it in pure BASIC code and 2D plotting.
Key elements of the program are the object array itself, which is declared with an unconventional column-row order to allow sorting by Z-coordinate:
Code: Select all
REM Array to hold the balls' positions in '3D space'
DIM p(2, NUMBALLS - 1)
Here the first subscript takes the value 0, 1 or 2 corresponding to the x, y and z-coordinates of the object respectively, and the second subscript is the object index. Then there is the rotation matrix, which is constructed from the rotations around the three axes:
Code: Select all
REM Rotation matrices
DIM a(2,2), b(2,2), c(2,2), r(2,2)
...
REM Create the rotation matrix
a() = 1, 0, 0, 0, COS(a), -SIN(a), 0, SIN(a), COS(a)
b() = COS(b), 0, SIN(b), 0, 1, 0, -SIN(b), 0, COS(b)
c() = COS(c), -SIN(c), 0, SIN(c), COS(c), 0, 0, 0, 1
r() = b() . a()
r() = c() . r()
(one could express it all in one go using the standard 3D rotation matrix but it's neater - and there is less opportunity for error - to let BBC BASIC calculate it).
Then finally there is the main rotation of the object array itself (and in this case also of the normals which are used for lighting):
Code: Select all
REM Rotate the 3D positions of the balls
REM (and also rotate the normal vectors)
q() = r() . p()
o() = r() . n()
I hope that's helpful.