Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Jesper T

cosinus function

This topic is 6096 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im not sure which forum this should go in blah blah, but here it is.. I made a function that calculates the cosine to an angle:
                

// definitions:


#define ONEPI  3.14159265358 // 97932384626433832795  
  

#define TWOPI  6.28318530717 // 95864769252867665590  // didnt need ALL those decimals lol    


#define PRES 25	    // Presicion, 25 makes it as presice as the cmath cos function 


// didnt gain so much speed by decreasing it (strange..)



// function:

double Cos( double ang )
{
  bool    cyc = true;
  int     u = 2;
  double  vrb[3];

  if( ang >  TWOPI ) { while( ang >  TWOPI ) { ang -= TWOPI; }}
  if( ang < -TWOPI ) { while( ang < -TWOPI ) { ang += TWOPI; }}

  vrb[2] = 1;

  while( u <= PRES )
  {
    vrb[0] = 1;
    vrb[1] = 1;

    for(int k = 1; k <= u; k++)
    {
      vrb[0] *= k;	// vrb[0] = u!

      vrb[1] *= ang;	// vrb[1] = ang^u

    }
    
    if(cyc)	
    {
      vrb[2] -= vrb[1] / vrb[0];
    }
    else 
    {
      vrb[2] += vrb[1] / vrb[0];
    }

    cyc = !cyc;
    u += 2;
    }
  return vrb[2];
}

    
What u think of it ? Can anyone think of a way to make it faster (without making it too inacurate)? Now it is about 99% the speed of the cmath cos function, but since this thing is placed directly into the source file it should be possible to make it faster.. right ? Edit: trying to make it readable.. Edited by - Jesper T on November 2, 2001 4:17:39 AM

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Some ideas:

* restrict the range more, e.g. to 0 to pi/2. The smaller the angle the quicker the power series will converge. Then use the properties of cosine, such as cos(-a) == cos(a), to derive the cosine for angles outside this range from this.
* the initial two lines to limit the range will take a long time with large input angles. If this is a problem consider using mod.
* precalculate the factorials instead of calculating them each time. Store them as 1/factorial to eliminate the need for the diviison. You can also store them as alternate + or -, eliminating the need for ''cyc'' to keep track of whether at odd or even term (though this makes them less useful generally).
* as well as a fixed number of iterations also test for the terms getting small enough. E.g exit the loop if ang^n/n! is less than some limit of accuracy.
* Use seperate floats instead of an array for the locals, as this will let the compiler allocate them to registers (though this is compiler/platform dependent).
* if you can get the number of iterations down consider unrolling the loop (again how much this helps is compiler/processor dependent).
* finally consider doing it another way: if speed is important a method using lookup and interpolation can be a lot faster, at a cost of extra storage for the lookup tables.

Share this post


Link to post
Share on other sites
GCC''s cosine function is much much faster than yours. Besides that, take out those clamp loops (they slow it down a lot). Just make sure that the user passes clamped data. Here''s an idea. Instead of your loops, try:
  
#define FOURPI 12.5663706143

// ...


while( ang > TWOPI ) { ang -= FOURPI; }
while( ang < -TWOPI ) { ang += TWOPI; }

That sped it up a lot in my tests (I was using a big number though). You probably don''t need those if''s, also. Anyway, my advise is still to use the built in cosine function .

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
ok, thanks for the tips

I tried this:

    

#define HLFPI 1.57079632679

#define ONEPI 3.14159265358

#define TWOPI 6.28318530717


double FACS[7] = { -0.5000000000000,
0.0416666666667,
-0.0013888888889,
0.0000248015873,
-0.0000002755731,
0.0000000020876,
-0.0000000000014 };



// function:


double Cos( double ang )
{
bool n = false;
double t;
double r = 1;
int e = 2;

if( ang < 0.0 ) { ang = -ang; }
while( ang > TWOPI ) { ang -= TWOPI; }
if( ang > ONEPI ) { ang = TWOPI - ang; }
if( ang > HLFPI ) { ang = ONEPI - ang; n = true; }

for(int f = 0; f < 6; f++)
{
t = ang;
for(int k = 1; k < e; k++)
{
t *= ang;
}
r += t * FACS[f];
e += 2;
}
if(n){ return -r; }
else { return r; }
}



By restricting the angle to: PI/2 > angle > 0 I only need to run the loop six times.. its seems _slightly_ faster, but I think that my system is a bit too unstable to do acurate tests on (lots of strange programs running in the background I think hehe)
Well I'll probably use the built in cosinus/sinus functions anyway, but its fun trying to do make ur own versions aswell

edit: eye cat'n toype corrctly

Edited by - Jesper T on November 2, 2001 5:50:21 AM

Share this post


Link to post
Share on other sites
quote:
Original post by Jesper T

"GCC''s cosine function"

whats GCC ?


GCC = "GNU Compiler Collection". Its a freeware compiler for multiple computer platforms, from the Free Software Foundation. It supports various languages including C, C++, Fortran, and others. You can easily write cross-platform console apps using GCC, and on free OS''s such as Linux you can access windowing libraries, OpenGL, etc. But it may not have good support (if any) for Windows application development, using Windows OpenGL, DirectX, or the Windows graphical interface though.

Check out: http://www.gnu.org/software/gcc/gcc.html

Oh, an "GNU" means "Gnu''s Not Unix"

Someone else probably can fill in some blanks on this.



Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.

Share this post


Link to post
Share on other sites
quote:
Original post by grhodes_at_work
But it may not have good support (if any) for Windows application development, using Windows OpenGL, DirectX, or the Windows graphical interface though.


The GCC compiler works fine for Windows development if you have a port of the Win32 libraries to GCC. Most people use the MinGW32 port, with Dev C++ as their IDE .

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!