#26664 - keldon - Wed Sep 22, 2004 3:57 pm
Instead of storing the actual sine (multiplied), store the recrical of 1 / sin(x). So for sin (106), which is 0.96, we will store 65536 * sin ( 106 ) (which is equal to 65536 / ( 1 / sin ( x ) ).
Now just multiply your value by sin [106], and wahay you've got it.
#26665 - getch - Wed Sep 22, 2004 4:03 pm
does that help with something?
#26667 - ampz - Wed Sep 22, 2004 6:16 pm
There is no reason to store more than a quarter of a sinewave. (0 to 90 degrees)
#26668 - jma - Wed Sep 22, 2004 6:25 pm
ampz wrote: |
There is no reason to store more than a quarter of a sinewave. (0 to 90 degrees) |
Sure there is: speed. Otherwise there is clamping of ranges, conditionals and extra math in there that isn't necessary. The question is whether or not you are using constants or variables. With constants you could do it yourself, and I agree 0-90 is just fine. With variables (ie, you're coding a library), speed may be more important.
Jeff
_________________
massung@gmail.com
http://www.retrobyte.org
#26669 - keldon - Wed Sep 22, 2004 6:29 pm
Was rushing because PC keeps resetting and did not read cern tutorials properly. It is the same calculation and method. Silly mistake really.
#26672 - Lord Graga - Wed Sep 22, 2004 8:52 pm
another option is to use the lovely BIOS function BGAffineSet to make a nice SIN/COS table :)
#26685 - ampz - Thu Sep 23, 2004 4:00 pm
jma wrote: |
ampz wrote: | There is no reason to store more than a quarter of a sinewave. (0 to 90 degrees) |
Sure there is: speed. Otherwise there is clamping of ranges, conditionals and extra math in there that isn't necessary. The question is whether or not you are using constants or variables. With constants you could do it yourself, and I agree 0-90 is just fine. With variables (ie, you're coding a library), speed may be more important.
Jeff |
Yes, a full sine wave provides slightly higher speed than a quarter sine, but there is only a few cycles difference. There is another aspect: With a small quarter wave table you might be able to easier fit it in fast RAM. It all depends on what resolution you need. If you only need 256 degrees resolution, then you don't save much by using a quarter sine, but if you need 4096 degrees, then it becomes a bit harder to fit it in RAM unless reduced to a quarter sine.
#26691 - tepples - Thu Sep 23, 2004 8:48 pm
And if you have even more things that would benefit from being in fast RAM, then given the ARM7TDMI CPU's fast multiplier, it might actually prove faster overall to do linear interpolation on a smaller table.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#27275 - AnthC - Thu Oct 07, 2004 11:31 pm
Here's code you can use to generate a sintable.
The advantages of this is that it fix into only a few lines of asm.
Values are scaled by (1<<24) so the sin of 90 will be (1<<24)
S32 SinTab[1024];
#define S64 long int
void MakeTab(void)
{
S64 k= 33553800;
S64 f0= 0;
S64 f1=-102943;
for (int i=0;i<1024;i++)
{
SinTab[i]=(S32)f0;
S64 tmp=f0;
f0=((f0*k)/(1<<24))-f1;
f1=tmp;
}
}
// 0..1024 is 0..360 degree so degrees angle*1024/360
int Sin(int angle)
{
return SinTab[angle&1023];
}
int Cos(int angle)
{
return SinTab[(angle-256)&1023];
}
#27276 - sajiimori - Thu Oct 07, 2004 11:49 pm
I think you need "long long" for 64 bits... "long int" is the same as "long", which is 32 bits on ARM GCC.
#27277 - poslundc - Fri Oct 08, 2004 12:58 am
Also: there is little reason to use a 64-bit sinetable, since you can only do 32-bit multiplication on the ARM. Assuming you do long-long multiplication, you will already want to get rid of most of the extra generated precision anyway.
Dan.
#27357 - AnthC - Mon Oct 11, 2004 12:08 pm
sajiimori wrote: |
I think you need "long long" for 64 bits... "long int" is the same as "long", which is 32 bits on ARM GCC. |
Yup that's true - should have tested it, usual problem when porting PC code which involves __int64 to the GBA.
Other comments -
The sintable is in 32 bit format, the process to generate it lazily uses 64 bit numbers/multiply.
#27365 - Lord Graga - Mon Oct 11, 2004 5:05 pm
AnthC wrote: |
S32 SinTab[1024];
#define S64 long int
void MakeTab(void)
{
S64 k= 33553800;
S64 f0= 0;
S64 f1=-102943;
for (int i=0;i<1024;i++)
{
SinTab[i]=(S32)f0;
S64 tmp=f0;
f0=((f0*k)/(1<<24))-f1;
f1=tmp;
}
}
// 0..1024 is 0..360 degree so degrees angle*1024/360
int Sin(int angle)
{
return SinTab[angle&1023];
}
int Cos(int angle)
{
return SinTab[(angle-256)&1023];
} |
Heh, looks like a thing that I saw in HUGI. They have a collection of coding articles up, they are well worth reading. More specifically, they have a whole article dedicated to creating SIN tables :).
There's also the BGAffine function to get the SIN/COS table, you may not forget.