Math Tricks by Brandon Williams
main index...

I just got through with my "Introduction to Trigonometry" tutorial and before I started the continuation of it I just wanted to put down a few math tricks I learned along the way that you can use in Flash. Some of these things have been covered in other tutorials and some have not but I just wanted to collect some of my ideas. There is not going to be all that much actionscript code (that will be up to you) but I will give you some background information on different things. Also please note that I did not have a chance to proof read this or check my work so if you find any mistakes please e-mail me.

I want to start with some equations of lines because we will be using that a lot throughout the rest of this. The standard form of the equation for a line really is not a form we can even use in Flash and just all around is not useful. It looks like this:

Ax + Bx = C

Where "x" is your independent variable or, basically, one that changes. I just wanted to give you that equation for your own reference but we will not talk about that very much. The next equation, which is probably the most widely known, is the slope-intercept form. It looks like this:

y = mx + b

Where "m" controls the slope of the line and "b" controls where the line intersects the y-axis. If you have two points (x1, y1) and (x2, y2) the slope can be found with this equation:

y2 - y1
-------- = m
x2 - x1

// or you might see this a lot \\

delta (y)
--------- = m
delta (x)

That basically means the difference of the y-positions of the two points divided by the difference of the x-positions. Keep in mind though that the order you subtract the two variables does not matter as long as its consistent. Meaning that these two equations will produce the correct answer:

y1 - y2
-------- = m
x1 - x2

// and \\

y2 - y1
-------- = m
x2 - x1

However these two will not:

y1 - y2
-------- = m
x2- x1

// and \\

y2 - y1
-------- = m
x1 - x2

A little bit more information concerning the slope: the higher the value of "m" the steeper the slope and vice versa. Also if the slope is a positive number the line will go from bottom-left to upper-right and a negative slope will, of course, do the opposite. The "x" is once again your independent variable: given an input of "x" your output is "y" thus your ordered pair is (x, y). Now that is a really useful equation to use in Flash however it is sometimes hard to find the value of "b" if you only know a few points on your line and the slope. That is when probably the most useful equation of a line comes into play: the point-slope form. It looks like this:

y - y1 = m(x - x1)

Where "x1" and "y1" are the x- and y-positions of a point (any point) on the line and "m" is once again the slope of the line. Now you may have noticed that the dependent variable "y" is not by itself on the left side of the equation. That pretty much renders the equation useless unless we can get it by itself. To do that we just add "y1" to both sides of the equation so that the y1's (plural) cancel out on the left side and you are left with this handy-dandy equation:

y = m(x - x1) + y1

Now when I started this I wanted to include the least amount of script possible so you could figure it out but I have a feeling I must give an example to show just how helpful that equation is. Lets say you have two movie clips on the stage named "point1" and "point2" and you want some other movie clip named "object" to move back and forth between the two no matter where "point1" and "point2" are. Now bear with me on this because this could be an entire tutorial by itself so my tutorial as a whole could get quite long.

Lets start by making our movie clips and naming them with the names I have given above. Edit your two movie clips and make the graphic inside of there a button and but these actions (Flash 4 syntax that way everyone will understand) :


On (Press)
Start Drag ("")
End On
On (Release)
Stop Drag
End On
You should only make "point1" and "point2" movie clips draggable. The "object" movie clip only needs to be a basic movie clip. Now on the main timeline create three keyframes. The first will be to start things off, the second will be our main actions, and the last will have a go to and play previous frame action.

Now that you know the basic layout of what we are trying let me give you a run-down of the concept. First we want to find the equation of the line that connects the two draggable movie clips like we have done before. We know how to find the slope and a point on the line so that should be no problem. We then want to plug in an "x" value that is between the two movie clips into our equation which will return a "y" value. That will be the ordered pair that our "object" movie clip will be placed. We then add a small value to "x" and re-plug in it into the equation so that we get a new "y". By adding a small value to the "x" variable we are sliding the "object" along the x-axis and then our equation of the line regulates the "y" variable so that the "object" will look like its staying on a line between the two other movie clips. But when "object" gets to one side we need to set that value that controls the step to its opposite so that the "x" will go the other way. Well enough talk…here is the code I would use:

Frame One: Set Variable: "x" = GetProperty ("point1",_x) Set Variable: "step" = 2

Frame Two: Set Variable: "x1" = GetProperty ("point1",_x) Set Variable: "y1" = GetProperty ("point1",_y) Set Variable: "x2" = GetProperty ("point2",_x) Set Variable: "y2" = GetProperty ("point2",_y) Set Variable: "m" = (y1 - y2) / (x1 - x2) Set Variable: "y" = (m * (x - x1)) + y1 SetProperty ("object", X Position) = x SetProperty ("object", Y Position) = y Set Variable: "x" = x + step

Frame Three: If (x >= GetProperty ("point2",_x)) Set Variable: "step" = step * -1 Set Variable: "x" = GetProperty ("point2",_x) Else If (x <= GetProperty ("point1",_x)) Set Variable: "step" = step * -1 Set Variable: "x" = GetProperty ("point1",_x) End If Go to and Play (_currentframe - 1)

If I have explained this good enough that should be somewhat self-explanatory but I will add in some more comments. The first frame is to set "x" to the x-position of "point1" because that is where we want the "object" to start from. The "step" variable controls how fast the "object" moves between the other two movie clips. The second frame is where all our main stuff is. I used the same variable names that we talked about earlier so that it would be easier to follow. We have "x1", "y1", "x2", and "y2" set first that will hold the x- and y-positions of our "point" movie clips. From those variables we are able to derive the slope of the line that would connect the two points with the same formula we used way above. Now we have the slope of the line and also a point on the line (we could use either the x- and y-positions of "point1" or "point2"…both would give us the same answer) so we can use the point-slope form of the equation of a line to find our "y" coordinate given an "x" coordinate. So that's exactly what we do in the sixth line of that code. Then the easy part is setting the x- and y-positions of "object" equal to the coordinate we found before hand in the script. And finally in the second frame code you set the independent variable "x" equal to itself plus the step variable.

Now if anything the third frame script should be the hardest to understand because it is not something we really discussed. Basically it checks if the objects' x-position has gone past that of point2's which is on the right side of the screen. If it has then you set "step" to its opposite so that the object will go in the opposite direction and you set "x" equal to the x-position of "point2". The reason I did that last step was because I found that on certain occasions the "object" would get to the end and then just pivot at the end and resetting "x" seemed to fix it. In the same script I also do the same to see if "x" has gone less than that of point1's, which is on the left side of the stage. I do the same thing for both "if" statements so there is really nothing more to explain.

Now that was only an example of some things we have learned so far. It was also a relatively simple example just so that you could get the feel of the better things to come. If you understand what we just did you should have no problem with the rest of this. If you do not get what we did then just stare at it until you finally understand. I also knocked up a quick example (in Flash 4) if you want:



You can download that fla here.


The next trick that could be useful is finding the point at which two lines intersect. I actually posted on a thread on the boards about this and when I started I did not know the answer but by the end I had gotten it. Let's start with some basics like finding where two lines intersect without even thinking of Flash or actionscript. Well if we were given two equations in slope-intercept form like this:

y = 3x + 2
y = .5x - 4

...we are basically wanting an input of "x" to give us the same output of "y" with both equations right. In simpler words: if I were to put in the same number for "x" for both equations and they both returned the same number for "y" wouldn't that mean that is where the two lines intersect? Well to do this on paper you would take the two equations, solve them for either "x" or "y" (get "x" or "y" on one side of the equation by itself) and then set the equations equal to each other and finally solve. Let's try that for the two equations above:

1.) Given y = 3x + 2 and y = .5x - 4 set them equal to each other:
3x + 2 = .5x - 4

2.) Subtract 2 from both sides to leave 3x by itself. The subtract .5x from both sides to get your x's on one side:
3x = .5x - 6 ---> 2.5x = -6

3.) Divide both sides by 2.5 to leave "x" by itself:
x = -2.4

You have just found the x-coordinate at which the two lines intersect. Now all you have to do is run -2.4 through one of the equations (it does not matter which one since they should both output the same thing) and then you have your y-coordinate. When I did it I came up with the number -5.2 for "y". So that would mean that the two lines intersect at (-2.4, -5.2). I also just checked it on my graphing calculator and it is correct. So that is easy enough on a piece of paper right? Well it gets much more complicated when trying to do that in actionscript. First of all we cannot just set two equations equal to each other. We have to derive our own equations if given two other equations. This had me stumped for quite awhile and then I realized I was just overlooking something pretty simple. I wish I could scan the piece of paper I did all my work on but the only resolution I can use that makes my handwriting legible caused my computer to freeze...so I made a picture for you to look at. Now keep in mind what we want to do is go from two separate equations set equal to each other to just the independent variable, "x", by itself on one side of the equation:

This picture go really big so just click here to see it.

Now that equation at the bottom of the picture is the one we want to use in Flash. Just with a given of one point for each line and a slope of each line we can find the x-position at which the two lines intersect. Then we can input that value into one of the equations to get our "y" value. I'm not going to provide any sample code because I would rather you try it but if you feel you have nowhere else to go and really need a sample check out this thread: http://www.flashkit.com/board/showthread.php?threadid=32835 . That is the thread I posted on...it has basically the same explanation except with a sample file at the bottom of my post. It is in Flash 5 however. If you would like a file in Flash 4 just e-mail me.

Now another question that is asked frequently on the Flashkit boards is moving objects in a circular path around another object. This will be a really short explanation because I am not going to give any source out but I still encourage you to try it out yourself. Even if you have no need for it just try it so you can get the feel of it. The best way, in my opinion, to do this is to use parametric equations to map out the x- and y-coordinates. This uses some trigonometry but do not worry because you do not need to know any to do this. But for your own reference if you want you can read my "Introduction to Trigonometry" that will hopefully be put up at Flashkit within the next few weeks. However unless you are really quick at this stuff you may not be able to make the connection between my introduction and what we are doing here. The reason this works is somewhat out of our scope for now but we will get to that later down the road when we get to the unit circle in depth.

Well I typed all of that and still haven't started explaining how to achieve this effect. So lets start with the parametric equation:

x = r * cos (t)
y = r * sin (t)

The constant "r" controls your radius and "t" is the independent variable. On a parametric graph it would range from 0 to 2pi in radians or 0 to 360 in degrees. However we want an object to continuously spin around another so we wouldn't restrict "t" to just 2pi or 360 but instead let it go on forever. But, those equations will spin an object around the origin (0,0). To get the object to spin around a point simply add an x-center or y-center value.

x = r * cos (t) + xctr
y = r * sin (t) + yctr

That will make an object move in a circle around (xctr, yctr) with a radius of "r". If you are using Flash 4 you need to go somewhere and get a trig lookup table. There is one at http://www.moock.org/ and a few at Flashkit. Simply copy and paste all of the values for sine and cosine in the first frame of your movie. But keep in mind that the trig values are set by integer values of degrees. So if "t" ever equals 34.2 there will be no value in your lookup table for it so you need to use Flash's int() function to round it. If you are using Flash 5 then keep in mind that Flash's math objects like radians and not degrees. I know I said I was not going to provide any code for this one but I feel it will help you better understand so I'm going to break my rule. Here is a script you can use in Flash 4:


  First frame: 
  Set Variable: "speed" = 1 // the speed the movie will move
  Set Variable: "t" = 0 // initialize "t"
  Set Variable: "radius" = 100 // the radius of the circle your object will move along...it can be anything
  -- AND YOUR TRIG LIBRARY -- 

Frame two: If (t >= 360) Set Variable: "t" = 0 End If xctr = -- your center -- yctr = -- your center -- Set Variable: "x" = radius * Eval("COs" & Int(t)) Set Variable: "y" = radius * Eval("sin" & Int(t)) Set Property ("movie", X Position) = x Set Property ("movie", Y Position) = y Set Variable: "t" = t+speed
Frame Three: Go to and Play (_currentframe-1)


The speed variable is really the only thing in that above script that I haven't explained. It is of course the speed at which the object moves because if you look at the last line of the frame two script I set "t" equal to itself plus the speed. That way "t" increases which is the whole reason an object would move in a circular path...you need the angle to change. Also I set up a little "if" statement because our trig library only has values up to 360 so if "t" goes past 360 we set it back down to 0. The Flash 5 way of this would be the same except you would not need the lookup tables or the "if" statement regulating the values of "t".

OK what's next? This is a little bit more advanced but lets talk about vectors. I have a very limited amount of knowledge with vectors but from what I do know a vector consists of a magnitude (velocity) and a direction (angle). A lot of physics concepts and books deal with vectors but vectors do not really mean much in the Flash world so we have to be able to translate vectors into x- and y-velocities. Here is a picture of a vector (it may not be an entirely correct picture but you should be able to get the gist of it) :


Now if we wanted to get the x- and y-velocities from that then you need to imagine that vector kind of like this:


Everything has been easy enough so far right? Well we now need to use a little bit of trigonometry. Lets refresh ourselves on two basic trigonometric functions: sine and cosine. The sine of an angle in a right-trianlge (usually called theta) is the the opposite side of the triangle divided by the hypotenuse. The cosine of an angle in a right-triangle is the adjacent side divided by the hypotenuse. Here is a picture to help you understand what I am saying:


Now those "opposite" and "adjacent" sides are only for that angle theta. If we changed theta to be the other angle at the top of the triangle the "opposite" and "adjacent" would be switched. Also when an angle is in standard form like in that picture ( when I say standard I mean that one of the rays that makes up the angle is the x-axis) you can think of the opposite side as "y" and the adjacent side as "x". So here is what sine and cosine of theta would equal in that picture:



opposite
sin (theta) = ----------
hypotenuse
adjacent
COs (theta) = ----------
hypotenuse


-- or you can think of it like this --

y
sin (theta) = ----
r < - - "r" meaning hypotenuse also

x
COs (theta) = ----
r

Now that's all you have to know to translate the vectors...wasn't too hard was it? Lets put our newly found knowledge in terms of the vector picture we had a above.
                velY
sin (theta) = ---------
velocity

velX
COs (theta) = -----------
velocity


Now all you need to do is apply some very basic Algebra by multiplying both sides of the equations by "velocity" so that they cancel out on the right side and you are left with these two equations:

velocity * sin (theta) = velX

velocity * COs (theta) = velY
And now you are all set to translate vectors into x- and y-velocities. One of the cool things that I found you could make with this was a game that I used to play called "Bang!" It is where you have two players at opposite ends of some random terrain and you each take turns shooting cannonballs at each other by entering velocity and angle values...that is basically what we just did. Of course making a script for the random terrain and collision detection is a little different...it is actually much easier than what I just explained, so if you want some good practice with what we just talked about try and make it. I made a quick sample of the game and you can see it here (still buggy).

The last thing I am going to cover (briefly) is collision detection between two circles. Yes I know this has been done many times but I really have not seen an explanation of how it works. The first way and probably the preferred way for Flash 5 (not 4) is to simply take the distance between the two circles and subtract their radii from that distance...then if that goes below zero you know there is a collision. The equation would look something like:

sqrt ((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)) - r1 - r2 < 0
Where (x1,y1) is the ordered pair for one circle and (x2,y2) is the ordered pair for the other circle and r1 and r2 are the radii. So if the left side of the equation goes below zero then you have a collision.

Now that is good for Flash 5 because you have the square root function and I am told by Jobe Makar of ElectroTank that the square root is done on a machine level so you will not notice much difference if you did not use it. So Flash 5 can handle many collision detections like that. However Flash 4 did not have the square root function so everybody used Newton's square root method which converged very fast with the correct answers. You could get an accurate answer with only 10 iterations. But if you are checking collisions between 10 balls those iterations add up quickly and now all of a sudden you have 100 iterations on top of your other scripts...not good. So we need to be able to solve that above equation without the square root. Here is how I did it:
sqrt ((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)) - r1 - r2 < 0
-- now add r1 and r2 to both sides of the equation...r1 and r2 cancel out on the left side --
sqrt ((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)) < r1 + r2
-- now square both side of the equation so that the square root cancels out on the left --
(x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) < (r1 + r2) * (r1 + r2)
-- and that is all you need --

So if the left side of that last equations goes less than the right side you know you have a collision...very easy eh?

I was going to cover one more subject but this has gotten long enough so I will stop now. Have fun with these things and good luck. Also I just wanted to say that I am going to write a few things like this except that I have run out of ideas of what to write about next. I am definitely going to go more into trigonometry but if you have any other suggestions e-mail me.

Click here to download this tutorial.