Use fast trig in C on the X16

Tutorials and help articles.

(Posts require approval. See pinned post.)
Forum rules
Post guides, tutorials, and other instructional content here.

This topic area requires approval, so please be patient while we review content to make sure it fits the expectations for this topic area.

Tech support questions should be asked in Hardware or Software support.
rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »


I've started looking for easy, portable, fast and imprecise 8-bit trigonometric functions to use in the game I'm writing in C.

I've attached a 320 element binary table, with of course the obligatory initial two null bytes.  Use it like this:

foo = TRIG_TABLE[ x ];  // sin(x).  x is from 0 to 255, representing 0 to 360 degrees.
bar = TRIG_TABLE[ x + 64 ]; // cos(x).  

foo_sign = foo & 128;
foo_val = foo & 127;

bar_sign = bar & 128;
bar_val = bar & 127;

The indexed byte value has two parts: the 8th bit is the sign bit.  The remaining 7 bits represent the value, in hundredths.

Yazwho and Desertfish noted that sin and cos overlap, so only one table is needed, as long as you start COS indexing at an offset of 64 (= 90 degrees). In other words, cos(x) = sin(x+64). Since space isn't THAT critical, the table is 320 bytes long.

* * *

I found this interesting idea over here: https://geometricolor.wordpress.com/2017/01/06/fast-approximations-of-the-sine-and-cosine-functions/


Quote




The length of the table should be a power of 2 plus one for linear approximation. Then we can use bitwise-and (&) to impose periodicity instead of the much slower modulus (%) operation.



 

TRIG

x16tial
Posts: 177
Joined: Sun Feb 07, 2021 8:23 pm

Use fast trig in C on the X16

Post by x16tial »


How do BASICs trig functions work?  Tables of information might already be in ROM.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »



7 minutes ago, x16tial said:




How do BASICs trig functions work?  Tables of information might already be in ROM.



Nicely suggested.  You're right, I should look!

 

User avatar
Yazwho
Posts: 167
Joined: Fri Feb 19, 2021 2:59 pm
Contact:

Use fast trig in C on the X16

Post by Yazwho »



22 minutes ago, rje said:




My first assumption is that there could be two tables, one for sine, and one for cosine.



cos is just sin offset by 90 degrees, or 64 if you use a 256 byte table. So you can save yourself some ram at the expense of an add.

Depending on what you're trying to do, if it's possible to match the amplitude to what you need (so no multiplication is required) you'll obviously get better performance.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »


Commodore BASIC's SIN routine, after dividing the problem by quadrant, uses floating point math thus:


Quote




...It finally computes SIN(X) using the following polynomial, which approximates SIN(F2*2*π) over [-0.25, +0.25]:




-14.381390672 * F211 + 42.007797122 * F29 - 76.704170257 * F27 + 81.605223686 * F25 - 41.341702104 * F23 + 6.2831853069 * F2



...



SIN calls POLY1, which calls MLTPLY ($BA59), and consequently the multiply bug affects its results.




https://www.c64-wiki.com/wiki/SIN

User avatar
desertfish
Posts: 1097
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

Use fast trig in C on the X16

Post by desertfish »


Sin and cos overlap after .5 pi you can save a few hundred bytes with that

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »


Yaz mentioned that as well.  One overlapping table!

 

 

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »



1 hour ago, x16tial said:




How do BASICs trig functions work?  Tables of information might already be in ROM.



Now you've got me wondering what a BETTER but still not perfect sin/cos table would look like.  I mean, it could have 64K entries.

But at that point it's ridiculous, and so not only would it be divided into quadrants (thus shrinking to a 16K table) but I suspect speed would be sacrificed and an assembly routine would be introduced, and the result would land somewhere in between.

There's always https://en.wikipedia.org/wiki/Bhaskara_I's_sine_approximation_formula

image.png.69c2625dc12a438435da9c4720a5fb85.png

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Use fast trig in C on the X16

Post by rje »


It also didn't occur to me to find out what kind of trigonometric functions cc65 has, if any (I couldn't find them in cc65's library discussion).

 

Michael Parson
Posts: 51
Joined: Sun Jan 03, 2021 8:18 pm

Use fast trig in C on the X16

Post by Michael Parson »



58 minutes ago, rje said:




It also didn't occur to me to find out what kind of trigonometric functions cc65 has, if any (I couldn't find them in cc65's library discussion).



Unfortunately, none.  Anything that requires floats and/or math.h hasn't been implemented yet.  It seems to be due to how the 6502 does floating point vs the 'traditional' C implementation using IEEE 754.  There were discussions on the cc65 dev list a few years ago about it, and one guy seemed to be making progress, but nothing seems to have been committed to the master branch as of yet.

Post Reply