I just thought I’d share the code to a little experiment I did the other day after reminiscing about maths class.
From reading this post you’ll learn the following:
- How to find the derivative of a simple function
- Rotating an object to a relative point/angle (useful when shooting bullets, pointing towards mouse etc.
The derivative is the “slope of the line”, or “the number of Y a point will travel each X”. In the following example the derivative of the point following mouse is the red line.
How to find the derivative
The derivative can easily be found if a function is defined in the following form: z*x^n+m
So if the function is: F(x) = 3x^8+42
then the derivative is: F’(x) = 8*3^7+0
Do you see the pattern? Well the pattern can be expressed as the following:
F’(x) = n*x^(n-1)
if: F(x) = x^n
Any constant will be equal to zero in the derivative’s definition.
I won’t dig deeper into derivatives but in case you find it interesting check out this article.
So let’s write our function F and the function for retrieving the function’s derivative.
private function F(xx:Number):Number{
xx = k*Math.pow(xx,exp)+m;
return xx;
}
private function D(xx:Number):Number{
var dd:Number = exp*k*Math.pow(xx,exp-1);
return dd;
}
Drawing the derivative
Ok so we have a function that returns the derivative of our F-function. How do we draw the derivative on screen? Well we write the following function, run ut each frame with the current x as input. Note that the function D returns the derivative.
private function drawDerivative(xx:Number):void{
var offX:Number=350;
var offY:Number=offX*D(xx);
derPos1 = new Point(xx-offX,mouse.y-offY);
derPos2 = new Point(xx+offX,mouse.y+offY);
derivative.graphics.clear();
derivative.graphics.lineStyle(1,0x990000);
derivative.graphics.moveTo(derPos1.x,derPos1.y);
derivative.graphics.lineTo(derPos2.x,derPos2.y);
}
Easy and quite fancy, eh?
How to find the rotation
Ok, but let’s say we have a cool car we want to print on the slope, wheras in this case a cool square (oh that’s square). Finding the rotation is quite easy using the built in trigonometry functions. Just check this out.
private function R(xx:Number):Number{ //Rotation
var deltaX:Number = derPos1.x-derPos2.x;
var deltaY:Number = derPos1.y-derPos2.y;
var rot:Number = Math.atan2(deltaY, deltaX) * 180 / Math.PI +90;
return rot;
}
I won’t dig deeper into the trigonometry behind this, but it’s actually really easy and if you wish to understand it – take a peek at this article.
The full code
derivatives.fla:
var matrix:Matrix=new Matrix(); matrix.x=matrix.myW/2; matrix.y=matrix.myH/2; addChild(matrix);
matrix.as:
package{
import flash.display.MovieClip;
import flash.events.Event;
import flash.geom.Point;
public class Matrix extends MovieClip{
public var myW:Number=400;
public var myH:Number=300;
/* CHANGABLE */
var exp:Number=3;
var k:Number=0.000018;
var m:Number=0;
/* CHANGABLE */
var matrix,graph,mouse,derivative,square:MovieClip;
var derPos1,derPos2:Point;
public function Matrix():void{
initMatrix();
initGraph();
initMouseListener();
}
/*----INIT BEGIN----*/
private function initMatrix():void{
matrix = new MovieClip();
for(var xxx:Number=-myW/2; xxx<=myW/2; xxx+=25){
if(xxx==0){
matrix.graphics.lineStyle(2);
}else{
matrix.graphics.lineStyle(1);
}
matrix.graphics.moveTo(xxx,-myH/2);
matrix.graphics.lineTo(xxx,myH/2);
}
for(var yyy:Number=-myH/2; yyy<=myH/2; yyy+=25){
if(yyy==0){
matrix.graphics.lineStyle(2);
}else{
matrix.graphics.lineStyle(1);
}
matrix.graphics.moveTo(-myW/2,yyy);
matrix.graphics.lineTo(myW/2,yyy);
}
matrix.alpha=0.2;
addChild(matrix);
}
private function initGraph():void{
graph = new MovieClip();
derivative = new MovieClip();
var startingX:Number=-500;
var graph:MovieClip=new MovieClip();
graph.graphics.lineStyle(1);
graph.graphics.moveTo(startingX,F(startingX)); ///This is where we start drawing
for(var xx:Number=startingX ; xx<=550 ; xx++){
graph.graphics.lineTo(xx, F(xx));
}
addChild(graph);
addChild(derivative);
}
private function initMouseListener():void{
mouse=new MovieClip();
mouse.graphics.beginFill(0xff0000);
mouse.graphics.drawCircle(0,0,5);
addChild(mouse);
initSquare();
addEventListener(Event.ENTER_FRAME,followMouse);
}
private function initSquare():void{
square = new MovieClip();
square.graphics.beginFill(0x0000FF);
square.graphics.drawRect(0,0,60,50);
square.graphics.endFill();
square.alpha=0.2;
addChild(square);
}
/*----INIT END----*/
private function F(xx:Number):Number{ //Any function
xx = k*Math.pow(xx,exp)+m;
return xx;
}
private function D(xx:Number):Number{ //Corresponding derivative of the "Any function"
var dd:Number = exp*k*Math.pow(xx,exp-1);
return dd;
}
private function R(xx:Number):Number{ //Rotation
var deltaX:Number = derPos1.x-derPos2.x;
var deltaY:Number = derPos1.y-derPos2.y;
var rot:Number = Math.atan2(deltaY, deltaX) * 180 / Math.PI +90;
return rot;
}
/*----ENTER FRAMES BEGIN----*/
private function followMouse(e:Event):void{
mouse.x = mouseX;
mouse.y = F(mouseX);
drawDerivative(mouse.x);
drawSquare(mouse.x);
}
private function drawDerivative(xx:Number):void{
var offX:Number=350;
var offY:Number=offX*D(xx);
derPos1 = new Point(xx-offX,mouse.y-offY);
derPos2 = new Point(xx+offX,mouse.y+offY);
derivative.graphics.clear();
derivative.graphics.lineStyle(1,0x990000);
derivative.graphics.moveTo(derPos1.x,derPos1.y);
derivative.graphics.lineTo(derPos2.x,derPos2.y);
}
private function drawSquare(xx:Number):void{
square.x=xx-2;
square.y=F(xx);
square.rotation=R(xx);
}
/*----ENTER FRAMES END----*/
}
}
I’m working on a game based upon this, so check back soon to know what’s comin’ at ya ![]()
Let me know what you think.
ah at last, I found your article once again. You have few useful tips for my school project. This time, I won’t forget to bookmark it.
Glad to hear
If you care to share your school project that’d be interesting.