Fast Sine & Cosine lookup tables
Posted: Sat Feb 23, 2008 4:53 pm
The following snippet is something I include to be able to get fast SIN & COS value estimates. Depending on the number of steps around the unity circle you choose to have, you can end up with an accuracy of at least six decimal places, which is good enough for most of my applications.
In this setup, I've traded memory for speed. I could have just pre-computed one SIN quadrant and derive all other quadrants as well as COS from that. Instead I choose to create tables for both, for the entire unity circle.
Please note the credit in the header.
enjoy!
In this setup, I've traded memory for speed. I could have just pre-computed one SIN quadrant and derive all other quadrants as well as COS from that. Instead I choose to create tables for both, for the entire unity circle.
Please note the credit in the header.
enjoy!
Code: Select all
; ---------------------------------------------------
; SIN-COS-tables.pbi
; ---------------------------------------------------
; precomputed global SIN/COS lookup tables are
; referenced by macros to reduce function call
; overhead and avoid trig conversion calculations
; - fSIN ( degrees ) ; fast sine
; - fCOS ( degrees ) ; fast cosine
; ---------------------------------------------------
; based on Kaeru Gaman's following PureBoard entry:
; http://www.purebasic.fr/german/viewtopic.php?t=5884
; ---------------------------------------------------
Global _Trig_Resolution_.w = 16384 ; steps around unity circle, needs
; to be a power of 2, i.e.
; 512, 1024, 2048, 4096, 8192, ...
; the larger this value, the larger
; the tables become, but one also
; gets more precision
Global _Resolution_minus_One_.w = _Trig_Resolution_.w - 1
Global Dim SinTable.f(_Resolution_minus_One_.w)
Global Dim CosTable.f(_Resolution_minus_One_.w)
Global Angle_to_Index.f = ( _Trig_Resolution_ / 360.0 )
_Trig_Res_halved_.w = _Trig_Resolution_.w >> 1 ; populate tables
For n = 0 To _Resolution_minus_One_.w
SinTable(n) = Sin( (#PI / _Trig_Res_halved_.w) * n )
CosTable(n) = Cos( (#PI / _Trig_Res_halved_.w) * n )
Next
Macro fSIN( degrees )
SinTable( Int((Angle_to_Index.f * degrees) + 0.5 ) & (_Resolution_minus_One_.w) )
EndMacro
Macro fCOS( degrees )
CosTable( Int((Angle_to_Index.f * degrees) + 0.5 ) & (_Resolution_minus_One_.w) )
EndMacro
; ------------------------------------------
; Usage
; ------------------------------------------
; set __UsageDefined__ to #True to test this
; file standalone
; ------------------------------------------
Define.b __UsageDefined__ = #True
If __UsageDefined__
For i = 0 To 359 Step 15
Debug( "SIN(" + Str(i)+") = " + StrD( fSIN( i ), 6) )
Debug( "COS(" + Str(i)+") = " + StrD( fCOS( i ), 6) )
Next
EndIf