#16992 - Lupin - Sat Feb 28, 2004 2:15 pm
I know about the swi 0xE(0000) function, but it is not precise enough, i need a sinus/cosinus where 960 is a full rotation (4 times the display width) and i need it to be a 16 bit fixed point number, i tried using the swi function but since it can only calculate at 8 bit precision i got some troubles with it :(
At the moment I am using this line:
trigVox[i] = (sin(i * 0.006544984694) * (0x10000));
It works pretty well, but i don't want to have software floating point calculations in my binary :/
Does anyone know a way to calculate sin on hardware without using floating point arithemtic?
I am also searching for a way to get a fast ArcTan2 function....
#16993 - Touchstone - Sat Feb 28, 2004 2:25 pm
Have you though of creating a sin look-up table on your PC and use it in your GBA program? Shouldn't use to much ROM space.
_________________
You can't beat our meat
#16996 - poslundc - Sat Feb 28, 2004 3:46 pm
Do as Touchtone says... create the LUT on your PC (usually 8.24 is plenty of precision), then either access it from ROM or transfer it into EWRAM during your program's initialization phase.
If it's not too destructive to your mathematics, you should consider making your table 1024 entries instead of 960. Since sin/cos are periodic you can then easily find the correct function value for any number just by AND-ing it with 1023 beforehand.
And all you need is one LUT for both sine and cosine... if you make a cos table, just add 256 to your value before AND-ing to get the sine.
A 1024-entry table of 32-bit numbers will take only 4K of ROM, or 4K if you transfer it to EWRAM (out of 256K that you have available).
ArcTan2 is a bit trickier, since it is a function of two variables... but for a small enough range of inputs it should still be practical to use a LUT. Other than that, I imagine the BIOS function is at least decent, although I can't say I've tried it.
Dan.
#17008 - Lupin - Sat Feb 28, 2004 7:37 pm
well, i would like to know how to set up the bios function for using arctan2 :)
#17009 - Miked0801 - Sat Feb 28, 2004 7:54 pm
You could, but if precision matters that much, LUT it as well.
#17014 - poslundc - Sat Feb 28, 2004 9:51 pm
Lupin wrote: |
well, i would like to know how to set up the bios function for using arctan2 :) |
http://www.work.de/nocash/gbatek.htm#biosarithmeticfunctions
It's the last function in the section.
Dan.
#17019 - Lupin - Sun Feb 29, 2004 12:08 am
thx, do you know what is meant by integral part?
#17021 - poslundc - Sun Feb 29, 2004 12:53 am
The integral part of a number is everything left of the decimal place. Likewise, the fractional part is everything to the right of the decimal place.
Since the atan2 bios function only allows one bit of precision in the integral part, this means it only operates on the range (-2, 2). Which is a little unusual, but I guess you can always shift your inputs down to the correct precision.
Dan (woo, 500).
#17022 - ampz - Sun Feb 29, 2004 2:11 am
Remeber, when doing sine LUTs.. You only need the LUT for a quarter of a sine. Saves memory.
#17025 - tepples - Sun Feb 29, 2004 5:45 am
How to do sin:- Reflect theta into [-quarter circle, quarter circle]
- Store whether theta < 0 ("quadrant info")
- Do a table lookup on |theta|
- Combine with quadrant info
How to do cos:
Code: |
static inline fixed fixcos(fixed theta)
{
return fixsin(theta + QUARTER_CIRCLE);
} |
How to do arctan2:- Store whether Y and X are negative ("octant info")
- Store whether |Y| is greater than |X| ("octant info")
- Fix-divide smaller absolute value by larger absolute value
- Do a table lookup on the quotient
- Combine result with octant info
You can save even more memory on the lookup tables used by cos and arctan2 by using linear interpolation rather than nearest-neighbor, which gets you the same mean error with shorter tables.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#17027 - poslundc - Sun Feb 29, 2004 6:08 am
There is a good argument to be made for the redundant data of a complete sine or cosine table... most applications don't need higher resolution than a kilobyte or two of data anyway. My cosine table has 512 entries (2K) for a complete circle, which is already way more than I need for my raycaster. And even if you need, say, four times that level of detail (which is now quite a lot of resolution), what's the big deal with using 8K of EWRAM?
Typically where math is involved I am also concerned with speed, and it's nice to be able to pull a result out of EWRAM in less than ten cycles.
Not that these other techniques aren't valid... but where speed is a factor you can't beat a comfortably redundant LUT. :D
Dan.
#17034 - Lupin - Sun Feb 29, 2004 10:49 am
Who minds about memory? I have 32kb IWRAM, that's more than i will ever need lol :P