Trig
Many people think you have to be some sort of university
math’s freak to do all this trigonometry stuff. Well, I’d like to tell you that
you don’t, since I’m 16 and although I do fairly well in math’s at school, I’m
no freak.
Degrees and radians
Now I don’t know about you, but when I measure an angle, I
measure it in degrees. Well VB measures angles in Radians. With radians, there
are 2pi of them in a circle. So: 2pi radians = 360 degrees. With that cleared
up, we might want to write some functions to convert between radians and
degrees.
The first thing I will point out is that because VB uses
radians to give angles, we can get a pretty accurate version of pi by using
this formula:
Pi = Atn(1) * 4
Which equals: 3.14159265358979. That should be accurate
enough for our needs :)
Now if you are in my target audience, then you probably
don’t know how or why this works, but by the end of the tutorial, I hope you
do.
So to get radians from degrees:
Function DegToRad(Degrees As Double) As Double
DegToRad = Degrees
/ 180 * Pi
End Function
And the opposite:
Function RadToDeg(Radians As Double) As Double
RadToDeg =
Radians * 180 / Pi
End Function
Note that we are using division here when it is not
absolutely necessary (division is slower than multiplication for computers) so
we could optimize our functions by creating two constants:
Const D2R As Double = 1 / (180 * Pi)
Const R2D As Double = 180 * Pi
(Note that “x / y” is the same as “x * (1 / y)”)
And the new functions are simply:
DegToRad = Degrees * D2R
and
RadToDeg = Radians * R2D
Triangles
Ok, so now we can measure angles... hooray :)
Since we are doing trigonometry, we will be working with
triangles (hence “trigonometry”). And since this is a fairly simple
tutorial, we will work with right angled triangles. Right angled triangles are
simply triangles with a right angle (did you know you can draw a triangle with
3 right angles if you draw it on a sphere?).
Naming the sides of a triangle is done like this:

The most important thing to note here is that the angle we
are trying to find out is the one on the right (with the curvey bit on it).
So the side that is opposite our angle is called the (drum
roll)... “opposite”.
Now there are two sides adjacent to our angle, so how do we
distinguish between them? Well, because this is a right angled triangle, we
have the “hypotenuse” which is the side which is opposite the right angle... it
is also the longest side in all cases.
So we can name the hypotenuse “hypotenuse” which leaves us
with one more side to name, the “adjacent” which coincidently is adjacent to
our angle.
Well that was fun wasn’t it.
SOHCAHTOA
Sin(Theta) = Opposite / Hypotenuse
Cos(Theta) = Adjacent / Hypotenuse
Tan(Theta) = Opposite / Adjacent
What???????
Theta is our angle and Opposite, Adjacent and Hypotenuse are
our side lengths.
So if we know the angle we are trying to find out, we can
then work towards getting the side lengths in our triangle. But notice that
instead of simply returning a side length, it returns a ratio of one side
length to another. So if we know that the hypotenuse is 5 and the angle is 45
(working in degrees now) then:
Sin(45) = Opposite / 5
And I can tell you that
Sin(45) = 0.707106781...
So we know that:
0.707106781... = Opposite / 5
Now if we do the same thing to both sides of an equation, it
will always remain true, so if I multiply both sides by 5:
3.535533906... = Opposite
So we have just worked out the length of the side opposite
to our angle.
Points
You deal with points all the time, every time you blt a
picture to the screen, you specify some points (or coordinates) which you are
going to blt to.
When we are doing stuff with right angled triangles, to make
things easier for us, we make it so that one side is vertical, one side is
horizontal and one side is sloped. So:

We don’t want to have to work out more angles than is
necessary, so by using the 3 good triangles (give you a hint, the top left one
is stupid) we only have to work out one angle since we know that vertical is 0
and horizontal is 90 (or Pi / 2 in radians).
So in a game we might have two space ships (now I know Lucky
will like this tutorial), if we put one on one angle, one on another angle and
left the right angle floating around somewhere, we have a nice little triangle
which we can use to work things out.
So if one space ship is at (x1, y1) and the other is at (x2,
y2) then:
Opposite = Abs(x2 - x1)
Adjacent = Abs(y1 - y2)
Hypotenuse = Sqr(Opposite ^ 2 + Adjacent ^ 2)
Note:
Abs will return the absolute value of a number, so if it is
negative, it makes it positive.
Abs(-5) = 5
Abs(2) = 2
Abs(-.5) = .5
Speed tip:
Using:
Hypotenuse = Sqr(Opposite * Opposite + Adjacent * Adjacent)
will be faster than using the ^ 2 operators. This is because
^ is actually a function and it does lots of stuff so.... yeah, it is slower :)
Finding the distance
Hey look, the hypotenuse is a straight line between the two
space ships, and we have already worked out the length of the hypotenuse, so I
simply have to write:
DistanceBetweenShips = Hypotenuse
Finding the angle
Sin(Theta) = Opposite / Hypotenuse
Cos(Theta) = Adjacent / Hypotenuse
Tan(Theta) = Opposite / Adjacent
hmmm, these functions all seem nice, except for them to
work, you have to supply the angle (theta) and then it tells you the sides. We
want it the other way around, we wan’t to tell it the side lengths and get the
angle.
Introducing “Atn” I think it is a abbreviated form of “Arc
Tangent” but I think of it as “Anti Tan” basically, it is the opposite of Tan:
Tan(Theta) = Opposite / Adjacent
Atn(Opposite / Adjacent) = Theta
Wow, that’s fantastic, we can get the angle simply using
that?
Well, almost.
The problem is that our side lengths will always be
positive, and as such, all the angles we get will be confined to the 90 degree
sector to the top right of our circle.
To fix this up, we just work out what direction is should be
going in, and correct the new angle as such, the code I used to do this was
messy (used lots of Select Cases) so I’m stealing Lucky’s code and making a few
modifications: (I’m sure he won’t mind :)
If y2 = y1 Then
If (x2 -
x1) < 0 Then Angle = 3 * Pi / 2
If (x2 - x1) > 0 Then Angle =
Pi / 2
Else
If (y2 - y1) > 0 Then Angle =
Atn((x2 - x1) / (y2 - y1))
If (y2 - y1) < 0 Then Angle =
Atn((x2 - x1) / (y2 - y1)) + Pi
End if
So first, we see if the ships are in line with each other
horizontally (if they both have the same “y” coordinate, then they must be. In
this case, then our equation:
Tan(Angle) = Opposite / Adjacent
would have something like this:
Tan(Angle) = Opposite / 0
which would result in a “Divide by 0” error.
Because of this, there are two exceptions, which are
straight left and straight right. Fortunately, it is easy to calculate whether
something is to the left of or to the right of something by simply checking
which x coordinate is larger.
So with those exceptions out of the way, we can do the main
bit of the equation fairly simply, we just need to add 180 degrees (Pi radians)
depending on whether the ship is above or below our ship.
Finding a point given an angle, a point and a distance
Picture the classic QBasic game Gorila, you typed in an
angle and a power, and then the gorilla would throw a banana in the direction
you specified. How do you know how far to move the banana?
For this, we will use Sin and Cos. Now our Gorilla is
conveniently located at the point (0, 0) and is aiming at 35 degrees with a
power of 15.
If we draw a triangle with one point at (0, 0) and another
15 units away at 35 degrees and then another point in a convenient location to
make a right angle, we have a nice little triangle to work with.
What do we know about it? We know the angle, and the
hypotenuse. So here comes Sin and Cos:
Sin(Theta) = Opposite / Hypotenuse
Cos(Theta) = Adjacent / Hypotenuse
Now depending on how you drew your triangle, Opposite will
correspond to either X or Y and Adjacent will correspond to the other axis, but
let’s say that the Opposite is the X coordinate and Adjacent is the Y
coordinate. So we can substitute a few things into our equations:
Sin(35 degrees) = x / 15
Cos(35 degrees) = y / 15
Then we multiply both sides by 15:
Sin(35 degrees) * 15 = x
Cos(35 degrees) * 15 = y
and now all we have to do is convert the units into radians
and we can work out the coordinates for the banana to be at for the next frame
:)
x = Sin(DegreesToRadians(Angle)) * Power
y = Sin(DegreesToRadians(Angle)) * Power
And that is all there is to it (no exceptions in this one :)
Hope this has been a help, but if you have any questions
then don’t be afraid to ask: ragonastick@whale-mail.com
And I’ll probably be at the message board anyway.