gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > libnds SIN/COS/TAN look up tables

#99381 - Goosey - Mon Aug 21, 2006 5:29 am

I am trying to convert Patater's 'orange ship' tutorial ( http://www.patatersoft.info/manual.html ) to use fixed point math as a training exercise for myself.

I finished the conversion except for the Accelleration function which had the sin/cos math functions. Attempting to convert these to use the libnds luts has been a headache. I think I am missing something simple, but can't seem to find it.

For reference:
- Angles are being stored as RADIANS in signed 20.12 fixed format
- AFAIK the SIN/COS luts are 4.12 fixed format and 512 degree increments

Here is what I have tried for indexing based on the suggestions from people in #dsdev. Below the macros is the function where they are being applied.

Code:

#define f32slowsin( _rad )   ( floattof32(sin(f32tofloat(_rad))) )
#define f32slowcos( _rad )   ( floattof32(cos(f32tofloat(_rad))) )
#define f32slowtan( _rad )   ( floattof32(tan(f32tofloat(_rad))) )

#define PI         ( 3.14159265358979323846264338327f )
#define F32PI         ( floattof32(PI) )
#define RadToDeg512Mul      ( divf32(inttof32(256), F32PI) )
#define Deg512ToRadMul      ( divf32(F32PI, inttof32(256)) )

#define lutIndexMul      ( divf32( inttof32(512), mulf32(inttof32(2), F32PI) ) )
#define lutIndex( _rad )   ( mulf32( _rad, lutIndexMul ) )

#define radToDeg512PROPER( _rad )   ( mulf32( _rad, RadToDeg512Mul) )
#define deg512ToRadPROPER( _deg )   ( mulf32( _deg, Deg512ToRadMul) )

#define radToDeg512( _rad )   ( f32(f32tofloat(_rad) * (256/PI)) )
#define deg512ToRad( _deg )   ( f32(f32tofloat(_deg) * (PI/256)) )

// This causes the accel to be perpendicular (looking N and accel = E, deccel = W)
#define f32sin( _rad )      ( COS[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32cos( _rad )      ( SIN[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32tan( _rad )      ( TAN[radToDeg512PROPER(_rad) & 0x1FF] )

// This functions the same as above (I don't understand why, since the non-PROPER doesn't seem.. well, proper)
//#define f32sin( _rad )   ( COS[radToDeg512(_rad) & 0x1FF] )
//#define f32cos( _rad )   ( SIN[radToDeg512(_rad) & 0x1FF] )
//#define f32tan( _rad )   ( TAN[radToDeg512(_rad) & 0x1FF] )

// This also functions the same as the above two (OK NOW I AM REALLY CONFUSED! the above at least feed 512 DEGs, this feeds RADIANS!)
//#define f32sin( _rad )   ( COS[_rad & 0x1FF] )
//#define f32cos( _rad )   ( SIN[_rad & 0x1FF] )
//#define f32tan( _rad )   ( TAN[_rad & 0x1FF] )

// For the love of crap.. This also seems to behave the same as the 3 above. What am I missing? -_-
// #define f32sin( _rad )   ( COS[lutIndex(_rad) & 0x1FF] )
// #define f32cos( _rad )   ( SIN[lutIndex(_rad) & 0x1FF] )
// #define f32tan( _rad )   ( TAN[lutIndex(_rad) & 0x1FF] )

// These work exactly as intended, except for them being slow of course
// #define f32sin( _rad )   ( f32slowsin( _rad ) )
// #define f32cos( _rad )   ( f32slowcos( _rad ) )
// #define f32tan( _rad )   ( f32slowtan( _rad ) )

void Ship::Accel(float amount)
{
   f32 f32Amount   = floattof32(amount);

   f32 incX   = mulf32(f32Amount, f32sin(m_Angle));
   f32 incY   = -(mulf32(f32Amount, f32cos(m_Angle)));

   m_Velocity.x += incX;
   m_Velocity.y += incY;

   if (m_Velocity.x > m_MaxSpeed)
      m_Velocity.x = m_MaxSpeed;
   if (m_Velocity.x < -m_MaxSpeed)
      m_Velocity.x = -m_MaxSpeed;

   if (m_Velocity.y > m_MaxSpeed)
      m_Velocity.y = m_MaxSpeed;
   if (m_Velocity.y < -m_MaxSpeed)
      m_Velocity.y = -m_MaxSpeed;
}



Any help would be greatly appreciated. At a frusterating point where I just simply don't understand where I am erring so I am randomly trying stuff in hope it will work. Not a fun place to be.

#99395 - Cearn - Mon Aug 21, 2006 8:55 am

Goosey wrote:
Code:
// This causes the accel to be perpendicular (looking N and accel = E, deccel = W)
#define f32sin( _rad )      ( COS[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32cos( _rad )      ( SIN[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32tan( _rad )      ( TAN[radToDeg512PROPER(_rad) & 0x1FF] )


You did notice that f32sin uses COS and f32cos uses SIN here, right? Or is this just an error in copying?

#99425 - Goosey - Mon Aug 21, 2006 3:26 pm

Cearn wrote:
Goosey wrote:
Code:
// This causes the accel to be perpendicular (looking N and accel = E, deccel = W)
#define f32sin( _rad )      ( COS[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32cos( _rad )      ( SIN[radToDeg512PROPER(_rad) & 0x1FF] )
#define f32tan( _rad )      ( TAN[radToDeg512PROPER(_rad) & 0x1FF] )


You did notice that f32sin uses COS and f32cos uses SIN here, right? Or is this just an error in copying?


*smacks head really hard*

Ok thankyou. That was the stupid error I was looking for I assume. Ill double check when I get home, but it is consistent with the results. TY!

/crawls away to hide in a corner

EDIT:
Ok have it working now with:

Code:

#define f32sin( _rad )      ( SIN[radToDeg512(_rad) & 0x1FF] )
#define f32cos( _rad )      ( COS[radToDeg512(_rad) & 0x1FF] )
#define f32tan( _rad )      ( TAN[radToDeg512(_rad) & 0x1FF] )


Still a little confused why the 'nonproper' rad->deg conversion is the one that works, but ill tackle that later. Glad to have the ship moving properly using 100% fixed woo..