In this article, we'll look at some trigonometry, all from scratch. Never encountered trig before? No problem! However, once we've covered the basics, we'll take a look at some common coding applications, rather than delving too deeply into the theory.
[h2]Before we start...[/h2]
The core part of this subject is the use of the [b]trigonometric functions[/b]. A function is a mathematical object that takes one or more values, does something with them, and returns another value; these are of course analogous to functions in programming!
Some of the trigonometric functions we will be using take angles as a parameter, but depending on the language you are using, your functions may expect values in degrees or radians. If you're unfamiliar with radians, [url=http://www.socoder.net/index.php?article=37003]take a look here before continuing[/url]. Make sure you know which units your language uses, or you'll get weird results!
For simplicity, unless otherwise noted, we will be using degrees in this tutorial. By convention, 0 degrees is taken to be due east, and increasing the number of degrees moves us anticlockwise.
[h2]What is Trigonometry?[/h2]
Trigonometry, or trig for short (trigonometry is a pain to have to keep typing!), is a branch of mathematics related to some properties of triangles, but that then extends out much further. For our purposes, we shall consider a right-angled triangle, and one of its angles that isn't the right-angle.
[thumb]http://socoder.net/uploads/56/ep1_triangle.JPG[/thumb]
The angle we are considering is [i]theta[/i] (θ). The longest side in the triangle is the [i]hypotenuse[/i], labelled [i]H[/i]. Note that this is always 'opposite' the right-angle - i.e. the right-angle does not touch it. The side opposite [i]theta[/i] is labelled [i]O[/i] for opposite, and the other side is labelled [i]A[/i] for adjacent. We shall be referring to this triangle from now on.
[h2]Sine, Cosine and Tangent[/h2]
As mentioned, we will be using trig functions. You will need a calculator if you want to use them - except for a handful of specific values, you can't really calculate their outputs in your head.
Sine, cosine and tangent, usually written as sin, cos and tan, are the three most common trig functions. Each of them takes an angle and returns a ratio, and their behaviours are closely linked to our triangle above. If we take the sin, cos and tan of our angle [i]theta[/i], we find that:
sin(theta) = O / H
cos(theta) = A / H
tan(theta) = O / A
If you think about it, you will realise that sin and cos can only ever output values between -1 and 1 (the hypotenuse is always longer than each of the opposite and adjacent sides), and that tan(90), tan(270), etc cannot be evaluated (try to draw that triangle!). You will also need to accept the 'existence' of triangles with sides of negative or zero length to see how the full range of angles can be covered by these functions.
Rather than draw my own, here are what these functions look like when plotted, nicked from another site:
[imgs]https://revisionworld.com/sites/revisionworld.com/files/imce/sincostan.gif[/imgs]
(For the sake of completeness, there are three other similar trig functions...
cosec(theta) = H / O
sec(theta) = H / A
cotan(theta) = A / O
but these are just flipped versions of sin, cos and tan, so they are rarely used, and we won't be using them at all.)
To remember which trig function is which, there is the good old mnemonic SOHCAHTOA:
[b]S[/b]in [b]O[/b]pposite [b]H[/b]ypotenuse
[b]C[/b]os [b]A[/b]djacent [b]H[/b]ypotenuse
[b]T[/b]an [b]O[/b]pposite [b]A[/b]djacent
[h2]Inverse Functions[/h2]
Just as square has square root, the trig functions have inverses with which to 'undo' them. These are arcsin, arccos and arctan (also written with superscript '-1's to denote inverse, although I can't do superscripts here for some reason).
Since these are the inverses, whereas sin, cos and tan take an angle and give a ratio, arcsin, arccos and arctan take a ratio and give an angle. Also, of course, as inverses, arcsin(sin(x)) = x, arccos(cos(x)) = x, and arctan(tan(x)) = x (except when tan(x) is undefined).
[h2]What can we do with them?[/h2]
If you were being taught this for the first time in maths, you'd now go on to use these functions to take triangles that you know some information about, and calculate what the remaining unknown values are. However, this, alongside further conclusions of trigonometry such as the sine and cosine rules, doesn't have a great deal of application to programming, particularly of games, so now we shall consider some common things you might use trig for.
[h2]Full Movement in 2D[/h2]
Say you have a character in a top-down 2D world, and you want that character to move at 1 unit per second. If they just move up, down, left or right, that's easy - just add or subtract 1 from their x or y position, depending what was pressed. But what if they try to move down [b]and[/b] right at the same time? If you add 1 to both the x and y coordinates, then the character will actually have moved more than 1 unit! Using Pythagoras' Theorem, we see they would in fact move sqrt(1*1 + 1*1) = sqrt(2), or about 1.41 units. How do we resolve this?
Consider our triangle from before. If our character wants to move by [i]r[/i] units from their current position through [i]theta[/i] degrees from 0 degrees, that gives us some value of [i]theta[/i] and a hypotenuse of [i]r[/i]. Looking at the definitions of our trig functions, we see that:
sin(theta) = y / r
cos(theta) = x / r
...so:
x = r * cos(theta)
y = r * sin(theta)
[thumb]http://socoder.net/uploads/56/ep1_movement.JPG[/thumb]
i.e. To move our character by [i]r[/i] units at [i]theta[/i] degrees, add r * cos(theta) to their x position and r * sin(theta) to their y position. In this way, more realistic motion can be achieved - for instance, if you were making an Asteroids clone, this is how you would move the spaceship, the asteroids, and the bullets.
[h2]Calculating Angles[/h2]
Now let's consider the reverse situation. Say our character has a gun, and can aim at where the mouse is pointing. Once we know what angle the bullet is going at, we can use our previous work to make it travel; but how do we know what that angle is?
Let's look at our old triangle again. We know the [i]x[/i] and [i]y[/i] distances from the character to the target, and we want to find [i]theta[/i].
[thumb]http://socoder.net/uploads/56/ep1_aiming.JPG[/thumb]
From our trig function definitions, we have:
tan(theta) = y / x
So, using the inverse function:
arctan(tan(theta)) = arctan(y / x)
theta = arctan(y / x)
Unfortunately, it is not that simple. The equation will fail if [i]x[/i] = 0, since we can't divide by 0, and our process doesn't hold if [i]theta[/i] was equal to 90, 270, etc, since tan doesn't evaluate for those values. Additionally, since the tan graph repeats itself every 180 degrees, we can't get an angle within the full 0-360 degree range.
Fortunately, most programming languages implement a function called [b]atan2[/b]. This function takes 2 values: the y value and the x value from our formula, and gives you the angle that you want, by taking special consideration of the whether the values are positive or negative, and if x is 0. Note that usually the y value is given [b]before[/b] the x value - this is because in the original formula, y also comes first.
So, to calculate the angle we are aiming at, we would typically use something like:
theta = atan2(aimY - charY, aimX - charX)
[h2]Summary[/h2]
[ul][li]The trig functions are sin, cos and tan.[/li]
[li]Remember how they are defined with SOHCAHTOA.[/li]
[li]Their inverses are arcsin, arccos and arctan.[/li]
[li]To move by r units in a direction of theta degrees, add r * cos(theta) to x and r * sin(theta) to y.[/li]
[li]To calculate the angle to something, use atan2(yDif, xDif).[/li][/ul]
Trigonometry goes a lot deeper, but unless you're doing something more geometric, you probably won't need much more than this. Next time, we'll change tack and look at vectors.
This post is from -- http://socoder.net/index.php?topic=0