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.

DS development > SIN, COS & TAN on libnds...

#53661 - Sephiroth87 - Sat Sep 10, 2005 11:39 am

hi there...
i was tryng to use those 3 functions, which are included in ndslib, but as far as i can see, they are not present on libnds (i've never understood the difference...)
is there a way to implement them?

#53663 - Sebbo - Sat Sep 10, 2005 12:32 pm

haven't done much coding for the DS myself (mainly just lurk on these forums and watch whats happening) but from what i understand you have to write your own sine tables etc (although once u have sine and cosine sorted out, tan = sin x / cos x)
_________________
Here's some ideas I have for when I know enough to act on them, or for others to have a look at when they're bored: www.wayne.sebbens.com/ds_ideas.htm

#53674 - falcon!!! - Sat Sep 10, 2005 2:34 pm

lol
io trigonometria la inizio questanno XD

#53680 - wintermute - Sat Sep 10, 2005 3:52 pm

#include <nds/arm9/trig_lut.h>

libnds & ndslib have always been largely identical. libnds was originally created when ndslib was going to be moving to devkitpro CVS and is just a cleaned up version which has been tested on all 3 supported host platforms. All development work has now moved to the devkitPro CVS and ndslib should be considered obsolete.

The main difference in terms of user code is that <nds.h> should be used rather than <nds/nds.h> and all headers are lower case. Windows is not case sensitive but it should be noted that linux and OS X are.

#53687 - Sephiroth87 - Sat Sep 10, 2005 6:14 pm

i've seen that file, but i've not the ***_bin.h that are #included...
so it wont works...

#53709 - wintermute - Sat Sep 10, 2005 9:31 pm

Sephiroth87 wrote:
i've seen that file, but i've not the ***_bin.h that are #included...
so it wont works...


update to the latest release of libnds ...

in fact, if you're using windows and nds dev env then uninstall nds dev env and use the devkitPro updater.

#53738 - Sephiroth87 - Sun Sep 11, 2005 9:42 am

ok, thank'you very much ;)

#76511 - knight0fdragon - Wed Mar 22, 2006 9:11 am

so what exactly is the tables returning, usually SIN is suppose to give a range of 1- < x < 1, but the table has shorts to them, should i cast them as floats to get the decimal?? also is this degrees or radians???, i would assume degrees since u need to place a whole number into the "array"
would this work or is there something i am missing here

v16 sine, cosine;

for(i = 0. ; i < 512. ; i++ )
{
sine = SIN[i];
cosine = COS[i];
}
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#76600 - tepples - Thu Mar 23, 2006 12:46 am

I think you should read the GBA beginners' FAQ and then look up fixed-point math.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#76611 - knight0fdragon - Thu Mar 23, 2006 1:39 am

i know what fixed point is, but that thing u sent he has nothing on how the sin table is represented, so i made my own using degrees so i know it works
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#76619 - tepples - Thu Mar 23, 2006 2:30 am

If you are using data types 'float' or 'double' in a GBA or Nintendo DS program, then your program will likely run extremely slowly. In order to not use data types 'float' or 'double', you'll need to learn to use fixed-point arithmetic.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#76632 - knight0fdragon - Thu Mar 23, 2006 3:44 am

im not using float or double, i am using v16 and f32 which i am assuming for f32 is 1.9.12 which would be sign int decimal correct?

so 7.5 would be 14336 int
i think the problem is i need to use the NDS math functions that are included with the lib

now what i need to know is are there any macros for say f32 x = 1.1
because im guessing that its treating it as an int so when i pass 1.1 into a variable it turns to 1 , and i dont want to multiply everytime by 4k
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#76648 - tepples - Thu Mar 23, 2006 4:59 am

If f32 is in fact a .12 fixed-point format, then try this:
Code:
#define float2f32(x) ((int)((x) * 4096))

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#76756 - ProblemBaby - Fri Mar 24, 2006 8:05 am

knight0fdragon wrote:
i know what fixed point is, but that thing u sent he has nothing on how the sin table is represented, so i made my own using degrees so i know it works


I strongly recommend you to use a better value than 360.
Use 256 or 512 entries instead so you simply can get around without having to use %

I aint sure about the ndslib but probably its 1:12 fixed or 1:8 reaching from 4096 to -4096 or 256 to -256.

And here is what entry 0,128,256.. is in degrees

0 = 0 degrees
128 = 90 degrees
256 = 180 degrees
384 = 270 degrees
512 = 360 degrees

hope you got it.

#76766 - knight0fdragon - Fri Mar 24, 2006 3:13 pm

i dont have to use mod, in fact the 360 looks pretty good for me, now so im guessing instead of haveing 360 degrees, we have 512 degrees to equal a complete circle? because i dont think its radians
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#76770 - strager - Fri Mar 24, 2006 4:25 pm

knight0fdragon wrote:
i dont have to use mod, in fact the 360 looks pretty good for me, now so im guessing instead of haveing 360 degrees, we have 512 degrees to equal a complete circle? because i dont think its radians

The libnds tables are 512 entries wide each to complete a full circle. This means that each unit is 2*pi/512 radians, or 360/512 degrees. They are in 4.12 format, suitable for the v16 format (I think), because it is used throughout the 3D code much.

#81037 - Chris Holmes - Wed Apr 26, 2006 9:12 pm

Are there any helper functions to look values up in the various tables?

Basically, I need the arctan function, which entails doing a binary search for the closest value in the tangent lookup table. Has someone already written that for libnds?

Thanks,
Chris

#81369 - Chris Holmes - Fri Apr 28, 2006 7:54 pm

Ok, so libnds includes three lookup tables, sin, cos, and tan.

It would have been immensely helpful if there had been either functions or #defined functions for sin, cos, and tan. The trig_lut header is just

And while I'm on it, there is no point in having a sin and a cosine table. You only need one table and can refence it for both. A nice sin function built for 360 degrees looks like:

Code:
inline v16 sin( int degrees ) {
  return( SIN_TABLE[ (degrees%360) >= 0 ? (degrees%360) : (degrees%360 + 360 ) ] );
}


if you want to use radians instead:

Code:
#define DEG2RAD floattof32(360.0f / 3.14159f)

inline v16 sin( f32 radians ) {
  return( sin( f32toint(radians * DEG2RAD)));
}



Sin and Cosine are generally accepted to be slow functions anyway, so making them take a slight performance hit should not be a big deal.

Cosine is of course built off the sin table.

Code:
inline cos( int degrees ) { return sin( 90 - degrees ); }

#define PI_OVER_2 floattof32( 3.14159f / 2.0f )
inline cos( f32 radians ) { return sin( PI_OVER_2 - radians ); }



The tangent table should be redefined to cover the range from -pi/2 to pi/2 as it is periodic at that point as well. The table should be defined this way so the range of the table is -infinity to infinity. Most importantly, this puts the elements in sorted order for a binary search. The current implementation, from what I can see, covers the range from 0 to 360 degrees.

Given this new tangent lookup table, implementing atan (tangent inverse) becomes as simple as identifying the quadrant, dividing y/x, and running a binary search over the elements of the tangent lookup table.

Anyway, I'll finish cleaning my implementation up and submit it to libnds.

Chris

#81375 - ecurtz - Fri Apr 28, 2006 9:30 pm

Chris Holmes wrote:
Sin and Cosine are generally accepted to be slow functions anyway, so making them take a slight performance hit should not be a big deal.


Which is why there is a look up table for them. Everything above is fine, but don't use 360 degrees, leave it at 512. Use a macro if you want 360 instead.

#81378 - Chris Holmes - Fri Apr 28, 2006 9:46 pm

Hmm.. well, I thought that doing 512 entries would mangle all the "common" angles like 45, 90, 180, but in reality, that ends up working out pretty alright.

So, converting from angles to the 512 entry is as easy as
( degrees * 512 / 360 ) which factors down to (degrees * 64 / 45 )

or

#define DEG2INDEX(n) (((n)<<6)/45)

The problem is that division. But if you really care about those angles in between 360, that's fine.

Chris

#82472 - Chris Holmes - Sat May 06, 2006 7:25 pm

I have a replacement math library for the current one. I submitted it as a comment to devkitpro.org, but in case anyone else wants it, I'm posting it here.

My libraries take up less space, provide f32's for tangent values instead of v16's (v16's can't cover the range of tangent nearly well enough), and I provide the ability to use the functions in direct mode (lookup directly from the table, degrees mode, and radians mode. I also provide the inverse sin,cos, and tan functions.

http://68.184.90.250:8080/dev/Trig.cpp
http://68.184.90.250:8080/dev/Trig.h

The entire source and makefile to build the test project is:

http://68.184.90.250:8080/dev/TrigTestProject.zip

A prebuilt .nds file is at
http://68.184.90.250:8080/dev/NDS.nds
http://68.184.90.250:8080/dev/NDS.ds.gba

I have tested this under Dualis (works fine) and on hardware (works fine).

There are three testing screens (press A to skip to the next one).
The first one compares the current look up tables in libnds to my computed values. libnds ones are displayed 4 pixels higher and in a darker color. The second screen tests my functions in degree mode from -360 to 720 degrees. The third screen tests my inverse functions by computing the values over the inverse allowed range (-90 to 90, or 0 to 180) and then using the inverse functions to drive the functions again to make sure they return the same values.

Chris

#82480 - wintermute - Sat May 06, 2006 8:56 pm

Completely unsuitable for inclusion in libnds.

How would a C program access this table?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#82482 - Chris Holmes - Sat May 06, 2006 9:01 pm

By removing the class structure. It doesn't need the class structure to work.

I built the class structure around it as an extra feature. If you want to remove it, just remove it. You only have to crop out about 5 lines.

Chris

#82484 - wintermute - Sat May 06, 2006 9:10 pm

I was attempting to make a point. Let's try again.

If you want to contribute to open libraries then you need to provide things in ways that the maintainers do not need to modify and fit in with the structure that's already there. Ideally this should be provided in the form of a patch against the current CVS HEAD which applies cleanly and has no side effects.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#82538 - Chris Holmes - Sun May 07, 2006 4:03 am

I'm replacing the math library. Further, I'm replacing the math library in such a way that it's guaranteed to break the examples. Because the original code provided no clean interface to the sin/cos/tan tables, providing a clean interface to my solution (removing the sin table) cannot be provided.

Therefore, I can't provide you with a clean patch for CVS that has no side effects. Therefore, I provided my working code complete with a test suite (how much code gets submitted with a test suite to validate it, really?). Integrating my changes can potentially break existing code. That's a Big Change and it's not as simple a thing as a CVS patch. Someone has to decide whether or not to include it at all, whether to include it on top of the existing infastructure, or whether to replace the existing infastructure.

I knew full well that the code would have to be modified at least slightly before inclusion to begin with. I don't care if it gets included or not. I found a feature missing that I wanted that other people could potentially be interested in, so I published the whole thing in the forums where anyone who wanted it could have it.

Instead of being rude to me and flaming me for trying to contribute something, why don't you (wintermute) and anyone else reading this on the devkitpro team decide if you want my contribution and if so, tell me what you would like me to do to make it easier for you to integrate it.
And if you don't want it, why not just say, "Thanks, but we don't want/need it." If you really don't want it, that's all you have to say. And anyone who does want it now has access to it.

Really, I had no idea the community was so damned mean spirited. Is it really so hard to be nice to people? I think it's a pretty easy thing. For example, I think that the work done on devkitpro is absolutely amazing and I thank everyone involved for their time, effort, and creativity. You people all did a great job!

Chris

#82552 - tepples - Sun May 07, 2006 6:51 am

Chris Holmes wrote:
I'm replacing the math library. Further, I'm replacing the math library in such a way that it's guaranteed to break the examples. Because the original code provided no clean interface to the sin/cos/tan tables, providing a clean interface to my solution (removing the sin table) cannot be provided.

Can you implement an API compatible with the old solution as a wrapper around your new solution so that the examples still build?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#82560 - melw - Sun May 07, 2006 7:54 am

In case of Chris Holmes' lookup's, backwards compability would look somethine like this (assuming current lookup uses also 512 values):

#define SIN(x) CosTable((x+128)%512)
#define COS(x) CosTable(x)

Not really rocket science, eh. :)

Trigonometry has never been any kind of bottleneck for me when developing for the DS, but just a quick points for both sides of the conversation: If Chris' proposed lookups provide better accurancy than the current one, also in smaller size (well, sin and cosine tables are basicly the one and same thing - can't see why you'd need to duplicate those tables anyways), updating the dev. environment sounds reasonable if done in a way not breaking the current trigonometric implementation.

#82595 - wintermute - Sun May 07, 2006 5:31 pm

Chris Holmes wrote:


Therefore, I can't provide you with a clean patch for CVS that has no side effects.


Yes you can, the examples are all in CVS too.

You also mailed this code asking how you get write access to the repository.

The response you got was a test. You failed.


There are several criteria we use for write access.

  • Can you modify your coding style to fit in with the project?
  • Are you capable of finding cases where your code breaks the existing examples?
  • Will you fix those cases which break or modify your contribution so that those cases don't break?
  • Will you take it personally if someone reports problems with your contribution in a terse manner?


In short, what I'm looking for is people whose contributions do not need vetted, critiqued in detail or create more work for other team members.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#82626 - Chris Holmes - Mon May 08, 2006 12:56 am

Quote:

#define SIN(x) CosTable((x+128)%512)
#define COS(x) CosTable(x)


The problem is actually that the examples do it like this:

SinTable[ value ]

I'm not entirely sure that #define allows [ in it, and that's the problem. I could easily change the Cos table to point to the new one, but the Sin table requires a modification exactly like you posted. But because the original directly accesses it like an array, I'm pretty sure that

#define SIN[n] SinTable[n]

is very much not valid. Hence the problem. If the original had used some accessor function like Sin(), then it would be easy to drop in a replacement.

Hmm...

Quote:
The response you got was a test. You failed.


Seriously dude, calm down. I asked for write access because if you said that yes, you wanted it, I was going to download the full source, integrate my changes, and then submit them to the project through CVS. It sounds like there's a way to generate a patch file through CVS instead of just checking files in. I'm sorry that I'm not a CVS expert. I don't like CVS at all and do all my work in subversion or another repository solution.

My point, as I explained and explained even more directly to melw is that my strategy would break existing code of other people who are using devkitpro.

And for the record, you weren't being terse, you were being mean. You told me privately that you felt like I was being impatient, so you went out of your way to make this a public fight and be mean to me. Seriously, I hoped people outgrew that when they finished college. Apparently, I was wrong. You said my code was completely unsuitable. Completely. You were wrong. 5 minutes of work would make it completely suitable.

You are simply being a dick.

That being said, I'm good. I made a contribution and was treated very poorly for doing so. Think of my contribution as a test of your leadership ability. You failed at being a leader. So I'll leave and find people who can work with others.

Chris

#82640 - tepples - Mon May 08, 2006 1:47 am

knight0fdragon wrote:
i dont have to use mod, in fact the 360 looks pretty good for me, now so im guessing instead of haveing 360 degrees, we have 512 degrees to equal a complete circle? because i dont think its radians

Almost, except you don't have 512 degrees; you have 512 half brads. In FutureBASIC (for Mac) and BASIC Stamp, the built-in trig functions use a unit called the brad, defined as 1/256 circle. The Allegro library (SDL's main competition) also uses brads.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#82641 - wintermute - Mon May 08, 2006 1:47 am

I'm perfectly calm.

On the other hand you appear to be reading a lot more into my words than is actually present.

I'm not trying to pick a fight here, merely replying to public responses in public. I had hoped for some mature discourse after asking how a C application would link to your code, I didn't get it.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog