Here are some fast trig lookup tables. The tables are populated using MAPM, but you could easily replace this with the built-in trig functions if you want. The results are not entirely accurate, but (I hope) accurate enough for a game and very fast.
Decimals are handled in an unusual way using integers. For example, 3600 is 360 degrees. 450 is 45 degrees. 705 is 70.5 degrees. For results, 1000 is 1.000. 743 is 0.743 5829 is 5.829. The factors for this are stored in constants. I haven't tested with other factors so I can't say that will work.
On my computer it takes 2 seconds to load all three tables, which isn't bad! To calculate every 0.1th angle from 0 to 360 degrees took 0 milliseconds for the fast trig and 2 milliseconds for built-in trig.
Strict
Import bah.mapm
Const trig_factor = 3, trig_ten = 10 ^ trig_factor
Const angle_factor = 1, angle_ten = 10 ^ 1, angle_360 = 360 * angle_ten
Function fix_angle:Int(angle:Int)
If angle >= 0
Return angle Mod angle_360
Else
Return angle - (angle_360 * (angle/angle_360 - 1))
End If
End Function
Global temp:TMAPM = New TMAPM
Global sin_table:Int[]
Function load_sin_table()
If sin_table.Length = 0
sin_table = New Int[angle_360]
For Local i = 0 Until angle_360
temp.SetDouble(i/Float(angle_ten))
Local result:TMAPM = temp.Sin(trig_factor)
temp.SetInt(trig_ten)
result = result.Multiply(temp)
sin_table[i] = Int(result.ToIntString())
Next
End If
End Function
Function fast_sin:Int(a)
Return sin_table[fix_angle(a)]
End Function
Global cos_table:Int[]
Function load_cos_table()
If cos_table.Length = 0
cos_table = New Int[angle_360]
For Local i = 0 Until angle_360
temp.SetDouble(i/Float(angle_ten))
Local result:TMAPM = temp.cos(trig_factor)
temp.SetInt(trig_ten)
result = result.Multiply(temp)
cos_table[i] = Int(result.ToIntString())
Next
End If
End Function
Function fast_cos:Int(a)
Return cos_table[fix_angle(a)]
End Function
Global tan_table:Int[]
Function load_tan_table()
If tan_table.Length = 0
tan_table = New Int[angle_360]
For Local i = 0 Until angle_360
temp.SetDouble(i/Float(angle_ten))
Local result:TMAPM = temp.tan(trig_factor)
temp.SetInt(trig_ten)
result = result.Multiply(temp)
tan_table[i] = Int(result.ToIntString())
Next
End If
End Function
Function fast_tan:Int(a)
Return tan_table[fix_angle(a)]
End Function
Function load_trig()
load_sin_table()
load_cos_table()
load_tan_table()
End Function
Local time
time = MilliSecs()
load_trig()
Print "It took " + String(MilliSecs()-time) + " milliseconds to load the tables."
time = MilliSecs()
For Local i = 0 To 3600
fast_sin(i)
fast_cos(i)
fast_tan(i)
Next
Print "It took " + String(MilliSecs()-time) + " milliseconds for fast trig."
time = MilliSecs()
For Local i:Float = 0 To 360 Step 0.1
Sin(i)
Cos(i)
Tan(i)
Next
Print "It took " + String(MilliSecs()-time) + " milliseconds for normal trig."
|