• entries
    743
  • comments
    1924
  • views
    579603

Sin and Cos

Sign in to follow this  
Aardvajk

110 views

No screenshots today. I've just been overhauling a lot of the underlying code base for Udo and making improvements where I can.

Most visual is that the starbursts that occur when you get stars or bounce on enemies heads have been vastly improved. I had previously hard-coded an array for the eight velocities that the particles needed to be initialised with but I decided that was a bit of a hack so I dusted off the maths part of my brain.

Now when the game starts, it precomputes float Sin[360] and float Cos[360] arrays so I can work with angles instead of radians and inverting the Cos array so that the angles work like my head wants them to.

I now pass a Count value to the CreateStarburst() call that states how many particles should radiate out from the centre. You can specify anything from 1, which would send a single particle straight up, to 360 which creates a rather daft solid expanding circle.

Just by increasing the Count to 16, I now have much cooler looking starburst effects. Plus I figure the Sin[] and Cos[] arrays will probably be really useful elsewhere as well if I want spinning stuff.

For posterity, here's the relevant functions:


float Sin[360];
float Cos[360];

void ComputeSinCos()
{
for(int I=0;I<360;++I)
{
float Ang=(float(M_PI*2.0)/360.0f)*float(I);

Sin=sin(Ang);
Cos=-cos(Ang);
}
}

void CreateStarburst(int Type,float X,float Y,int Count,float Speed,int List)
{
int W=ParticleTypes[Type].W;
int H=ParticleTypes[Type].H;

int Step=360/Count;

for(int I=0;I<360;I+=Step)
{
CBasicParticle *P=new CBasicParticle(Type,X-(W/2),Y-(H/2),Sin*Speed,Cos*Speed,30);
Items
    .Add(P);
    }
    }






Probably pretty simple from a math boffin's point of view but this is absolutley cutting edge maths from my simpleton's point of view so I'm quite pleased that all this sine and cosine stuff is starting to make sense to me.

Hopefully post some graphics sort of stuff later.

[EDIT]

No - scrap that. It only provides smoothly divided circles with exact integer divisibles of 360. Load of old rubbish. I still wanted to work with angles not radians, so instead, we now have:


float Sin(float A)
{
return float(sin(((M_PI*2.0)/360.0)*double(A)));
}

float Cos(float A)
{
return -float(cos(((M_PI*2.0)/360.0)*double(A)));
}

void CreateStarburst(int Type,float X,float Y,int Count,float Speed,int List)
{
int W=ParticleTypes[Type].W;
int H=ParticleTypes[Type].H;

float Step=360.0f/float(Count);

for(float I=0;I<360.0f;I+=Step)
{
CBasicParticle *P=new CBasicParticle(Type,X-(W/2),Y-(H/2),Sin(I)*Speed,Cos(I)*Speed,30);
Items
    .Add(P);
    }
    }





That will produce consistent gaps between particles with any number between 1 and 360. Lovely.

I figure that modern computers compute sin and cos pretty damn fast these days (I believe there are hardware instructions for it) so I'm not bothered about precomputing them. Seems to work perfectly now.

[EDIT AGAIN]

Thanks to Anon Mike in the comments below for simplifying my conversion functions. Actually, after that I'm wondering why I'm bothering to work with angles instead of radians at all. Think I'll go change that.

[EDIT]

Yeah, that's better. And I guess it was a bit dumb to have sin and Sin and cos and Cos in the same namespace. I'm just using sin and cos directly in the particle generation function now and it does seem a lot simpler.

Just goes to show how handy this journal is for getting your ideas subjected to decent criticism.
Sign in to follow this  


2 Comments


Recommended Comments

Having both sin and Sin seems a really good way to have some subtle but extremely difficult to find bugs.

Your conversion code would be a lot simpler if you just did return M_PI * A / 180.0f. I doubt all the extra casting is buying you anything. And what's up with the extra '-' in the Cos function?

Share this comment


Link to comment
Quote:
Original post by Anon Mike
Having both sin and Sin seems a really good way to have some subtle but extremely difficult to find bugs.


Not really. The definitions are local to this project and outside of these functions the math.h sin and cos won't be referenced anywhere. Perhaps not something I would use in library code though so I take your point.

Quote:
Original post by Anon Mike
Your conversion code would be a lot simpler if you just did return M_PI * A / 180.0f.


Yep - you are quite right. Thanks for that. New code:


float Sin(float A){ return float(sin(M_PI*A/180.0)); }
float Cos(float A){ return -float(cos(M_PI*A/180.0)); }


Quote:
Original post by Anon Mike
I doubt all the extra casting is buying you anything.


No. But it was also not costing me anything. The casts I've left in the above snippet supress VS's double to float conversion warning, since M_PI is double so promotes the other values and calls the double version of sin/cos.

Quote:
Original post by Anon Mike
And what's up with the extra '-' in the Cos function?


I want angle 0 to mean straight up, not straight down. That feels more intuitive to me given the direction the Y axis on a computer screen goes.

Thanks for the input. As I said above, I'm aware that this is not rocket science to anyone with a better understanding of maths than me.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now