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.