Some very useful angle functions
Posted: Sat Jul 10, 2010 2:42 am
Often you're making a game where movement and angles play a major part (which is exceedingly common in games). These are some functions that you'll quite likely want to use. You can save this script as a txt file in your local GE directiory, and then you can import it into Global Code. I end up doing this for practically every game I make, so it's well worth saving it in one common place.
As Fuzzy mentioned, you'll run into problems trying to wrap angles around a loop. I'm using a variation of his method to wrap the angles using angWrap.
This uses two other functions that convert between degrees and the WORD system, normToSpec and specToNorm. I don't normally use these functions directly, but the other functions do.
The next one is getangle. This one is especially awesome and you'll find yourself using it a lot. It measures the size of the angle between two anglesin the shortest direction, and returns a signed value. You can use abs (a built-in function) if you only care about the size of the angle, or sign if you only care about the direction.
Then we have ReDir. This rotates one direction towards another direction by a given angle.
ReDir calculates the size of the angle using getangle. But we don't know for ourselves what the size of the angle was. We could calculate it ourselves, but then we would be calculating the same thing twice, which is stupid. In this case we can use ReDir2, which makes us input the angle size, so we can calculate it, and know what it was.
So for example if we have an aeroplane, that is turning towards the mouse, we want it to bank to the right or left if it's turning sharply (which I did in World War Whatever: Air-Force).
Finally, we have xdist and ydist. These calculate cos and sin, respectively, for the given angle and multiply it by the given distance.
Okay, here are the functions:
Copy and paste into Global Code. Or copy into a text editor like notepad, and save it as a txt file for future use.
I hope you find these useful and if you have any questions about their uses, just ask.
As Fuzzy mentioned, you'll run into problems trying to wrap angles around a loop. I'm using a variation of his method to wrap the angles using angWrap.
This uses two other functions that convert between degrees and the WORD system, normToSpec and specToNorm. I don't normally use these functions directly, but the other functions do.
- Code: Select all
dir = angWrap(dir + 90); //will rotate dir by 90 degrees
The next one is getangle. This one is especially awesome and you'll find yourself using it a lot. It measures the size of the angle between two anglesin the shortest direction, and returns a signed value. You can use abs (a built-in function) if you only care about the size of the angle, or sign if you only care about the direction.
- Code: Select all
angsize = getangle(oldAngle, newAngle);//measure the size of the angle between the two directions
Then we have ReDir. This rotates one direction towards another direction by a given angle.
- Code: Select all
myAngle = ReDir(myAngle, mouseAngle, 10);//rotates myAngle towards mouseAngle by 10 degrees
ReDir calculates the size of the angle using getangle. But we don't know for ourselves what the size of the angle was. We could calculate it ourselves, but then we would be calculating the same thing twice, which is stupid. In this case we can use ReDir2, which makes us input the angle size, so we can calculate it, and know what it was.
So for example if we have an aeroplane, that is turning towards the mouse, we want it to bank to the right or left if it's turning sharply (which I did in World War Whatever: Air-Force).
- Code: Select all
double angSize = getangle(myAngle, mouseAngle);
myAngle = ReDir2(angSize, myAngle, mouseAngle, 10);
if (abs(angSize) > 20)
{
//banking animation
}
Finally, we have xdist and ydist. These calculate cos and sin, respectively, for the given angle and multiply it by the given distance.
- Code: Select all
x = xdist(mouseAngle, 20);
y = ydist(mouseAngle, 20);
Okay, here are the functions:
- Code: Select all
typedef unsigned short int specAng;
specAng normToSpec(double angsize)
{
return angsize * 182.04444444444444444444444444444;
}
double specToNorm(specAng angsize)
{
return angsize * 0.0054931640625000000000000000000013;
}
double angWrap(double angsize)
{
return specToNorm(normToSpec(angsize));
}
double getangle(double A, double B)
{
specAng NA = normToSpec(A);
specAng NB = normToSpec(B);
specAng result = NB - NA;
if (result > 32768)
{
return specToNorm(result) - 360;
}
else
{
return specToNorm(result);
}
}
double ReDir(double A, double B, double mag)
{
double ang = getangle(A, B);
if(abs(mag) <= abs(ang))
{
if(ang > 0)
{
return angWrap(A + mag);
}
else if (ang < 0)
{
return angWrap(A - mag);
}
else
{
return angWrap(A);
}
}
else
{
return angWrap(B);
}
}
double ReDir2(double ang, double A, double B, double mag)
{
if(abs(mag) <= abs(ang))
{
if(ang > 0)
{
return angWrap(A + mag);
}
else if (ang < 0)
{
return angWrap(A - mag);
}
else
{
return angWrap(A);
}
}
else
{
return angWrap(B);
}
}
double xdist(double angsize, double dist)
{
return cos(degtorad(angsize)) * dist;
}
double ydist(double angsize, double dist)
{
return sin(degtorad(angsize)) * -dist;
}
Copy and paste into Global Code. Or copy into a text editor like notepad, and save it as a txt file for future use.
I hope you find these useful and if you have any questions about their uses, just ask.