slmisc / gd32v-lcd

LCD library with DMA support for Sipeed Longan Nano (GD32VF103)
BSD 3-Clause "New" or "Revised" License
28 stars 1 forks source link

Explanation of Amiga ball code #3

Open tuupola opened 2 years ago

tuupola commented 2 years ago

Do you have any description on how the Amiga ball code works? I would like to implement it here but I would like to understand the code first.

slmisc commented 2 years ago

Sorry it took a while but here goes. The computations are done using fixed-point arithmetic, as the CPU doesn't support native floating-point calculations and emulation of those would be slow. It looks like at least 19.13 and 24.8 formats are being used, and there could be others in the mix.

There are three helper functions in amigaball.inl. w_approx approximates 1/sqrt(1-x^2) which is the inverse of the width of the sphere compared to the equator, depending on the vertical offset from center. The inverse is taken because to make the pattern shrink in x direction towards the poles, the x coordinate needs to be scaled up, and by baking the inverse into the function we can do it with a multiplication instead of division on line 65. The computation is a simple linearly interpolated table lookup.

The other helper function approx_asin gives an approxmation of arcsin(x), computed as a 5th-order Taylor polynomial. It is used to convert horizontal/vertical offsets into longitude/latitude angles on the sphere. Finally, c_remap implements a square wave pattern in 1D with short ramps between dark and light plateaus. These ramps gives the final pattern antialiasing between the colors.

The main function amigaBall is called for every pixel of the image. It first determines the pixel position relative to the ball center (53-56) and does a fixed-angle 2D rotation to tilt the ball a bit (58-59). It then checks if the pixel is too far from the center and exits if so (61-63). Then the rotated x and y offsets are converted to angles on the sphere, with x angle modulated by phase so that the pattern can spin (65-67). The angles are moduloed and the 1D pattern is evaluated for both x and y angles and then combined to form the checkerboard pattern (69-74). Finally, the RGB colors are decided and a slight fade is created at the silhouette of the ball to provide antialiasing (76-83).

The main program in main.c updates the frame buffer by calling the above function for all pixels (67-79). It also keeps track of position and velocity of the ball and updates them according to the gravity and bouncing off the walls and floor (88-93).

tuupola commented 2 years ago

Excellent. Thank you!