martes, 4 de agosto de 2009

Trace a Particle - Dibujar el camino de una Particula - Flex 3

Translation:

En este ejemplo podemos seguir la trayectoria de una animación en este caso una particular basada en formulas matemáticas. El seguir la trayectoria nos puede brindar información de donde estuvo una partícula o donde podrá estar en el futuro en caso de que sea una función cíclica.
This is an example of how we can trace an animation based in a Mathematical formula. The trace can give us information of the particle was in the past and if it’s a Cycle function were its going to be in the future.


En este caso usamos la fórmula para métrica del circulo, usando el sin y cos y colocamos variables dentro de la formula. La formula básica para la X y la Y es la siguiente:

X = sin( angle )* radius + initialPositionInX;
Y = cos( angle )* radius + initialPositionInY;

Para que podamos apreciar una animación necesitamos que el ángulo sea variable y un contador, también podemos colocar una velocidad a ese ángulo para que vaya más rápido.
Las formulas nos quedarían expresadas de la siguiente manera:

X = sin( time*velocityX )* radiusX + initialPositionInX;
Y = cos( time*velocityY )* radiusY + initialPositionInY;

Creamos una clase llamada particle y usamos una application para correrla:
Particle Class
package
{
import mx.core.UIComponent;

public class Particle extends UIComponent
{

/*---------------------------------------------------------------------------*/
/*----------------------------- START VARIABLES -----------------------------*/
/*---------------------------------------------------------------------------*/ 

private var _particleColor:uint = 0x000000;
private var _particleSize:int = 2;

/*---------------------------------------------------------------------------*/
/*------------------------------ END VARIABLES ------------------------------*/
/*---------------------------------------------------------------------------*/ 

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*--------------------------- START INIT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/

public function Particle()
{
super();
}

/*---------------------------------------------------------------------------*/
/*---------------------------- END INIT FUNCTIONS ---------------------------*/
/*---------------------------------------------------------------------------*/

/**************************************************************************/

/*---------------------------------------------------------------------------*/
/*------------------------------ START GET SET ------------------------------*/
/*---------------------------------------------------------------------------*/

public function get particleColor():uint{
return _particleColor;
}
public function set particleColor(value:uint):void{
_particleColor = value;
invalidateDisplayList();
}

public function get particleSize():int{
return _particleSize;
}
public function set particleSize(value:int):void{
_particleSize = value;
invalidateDisplayList();
}

/*---------------------------------------------------------------------------*/
/*------------------------------- END GET SET -------------------------------*/
/*---------------------------------------------------------------------------*/

/**************************************************************************/

/*---------------------------------------------------------------------------*/
/*------------------------- START OVERRIDE FUNCTION -------------------------*/
/*---------------------------------------------------------------------------*/

override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number): void 
{
super.updateDisplayList(_particleSize,_particleSize);
graphics.clear();
graphics.lineStyle(1,_particleColor,1);
graphics.beginFill(_particleColor,1);
graphics.drawCircle(0,0,_particleSize);
graphics.endFill();
}

/*---------------------------------------------------------------------------*/
/*------------------------- END OVERRIDE FUNCTION ---------------------------*/
/*---------------------------------------------------------------------------*/

}
}

The Application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" frameRate="120" 
creationComplete="creationCompleteHandler(event)" layout="absolute" 
width="415" height="300" backgroundColor="0xFFFFFF"  xmlns:local="*" 
backgroundGradientAlphas="[1.0, 1.0]" 
backgroundGradientColors="[#FFFFFF, #FFFFFF]" themeColor="#FFFFFF" 
borderColor="#000000" borderStyle="solid" >
<mx:Script>
<![CDATA[
import mx.events.NumericStepperEvent;
import mx.events.ColorPickerEvent;
import mx.controls.Image;
import mx.core.UIComponent;
import mx.events.FlexEvent;

/*---------------------------------------------------------------------------*/
/*----------------------------- START VARIABLES -----------------------------*/
/*---------------------------------------------------------------------------*/ 

private var time:Number =0;
private var xo:Number = 0;
private var yo:Number = 0;
private var velocityX:Number = 1;
private var velocityY:Number = 1;
private var radiusX:Number = 100;
private var radiusY:Number = 100;
private var myCont:Canvas;
private var myImage:Image;
private var myParticle:Particle;

/*---------------------------------------------------------------------------*/
/*------------------------------ END VARIABLES ------------------------------*/
/*---------------------------------------------------------------------------*/ 

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*--------------------------- START INIT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/

private function creationCompleteHandler(event:FlexEvent):void{
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
private function initParticleHandler(event:FlexEvent):void{
myCont = new Canvas;
myCont.percentWidth = 100;
myCont.percentHeight = 100;
myCanvas.addChild(myCont);
myParticle = new Particle;
myParticle.particleSize = 2;
myParticle.particleColor = 0xFF0000;
xo = myParticle.x = myCanvas.width/2;
yo = myParticle.y = myCanvas.height/2;
myImage = new Image;
myImage.percentWidth = 100;
myImage.percentHeight = 100;
myImage.alpha = 0.98;
myCont.addChild(myImage);
myCont.addChild(myParticle);
}

/*---------------------------------------------------------------------------*/
/*---------------------------- END INIT FUNCTIONS ---------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*-------------------------- START EVENT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/ 

/*-- START EVENT CAIRNGORM --*/

/*--- END EVENT CAIRNGORM ---*/

/***************************/

/*---- START EVENT FLEX -----*/
private function enterFrameHandler(event:Event):void{
time+=1/stage.frameRate;
myParticle.x = Math.sin(time*velocityX)*radiusX + xo; 
myParticle.y = Math.cos(time*velocityY)*radiusY + yo; 
myImage.source = new Bitmap(this.getUIComponentBitmapData(UIComponent(myCont)));
}
public function changeColorHandler(event:ColorPickerEvent):void{
myParticle.particleColor = event.color;
}
public function changeVelocityX(event:NumericStepperEvent):void{
velocityX = event.value;
}
public function changeVelocityY(event:NumericStepperEvent):void{
velocityY = event.value;
}
public function changeRadiusX(event:NumericStepperEvent):void{
radiusX = event.value;
}
public function changeRadiusY(event:NumericStepperEvent):void{
radiusY = event.value;
}
public function changeAlpha(event:NumericStepperEvent):void{
myImage.alpha = event.value;
}
public function changeRadius(event:NumericStepperEvent):void{
myParticle.particleSize = event.value;
}
public function clearImageHandler(event:MouseEvent):void{
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
myImage.source = new Bitmap();       
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}

/*----- END EVENT ------*/

/*---------------------------------------------------------------------------*/
/*-------------------------- END EVENT FUNCTIONS ----------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*-------------------------- START OTHER FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/ 

public function getUIComponentBitmapData( target : UIComponent ) : BitmapData
{ 
var bd : BitmapData = new BitmapData( target.width, target.height );
var m : Matrix = new Matrix();
bd.draw( target, m );
return bd;  
}

/*---------------------------------------------------------------------------*/
/*-------------------------- END OTHER FUNCTIONS ----------------------------*/
/*---------------------------------------------------------------------------*/

]]>
</mx:Script>
<mx:HBox width="100%" height="100%">
<mx:Canvas width="78%" height="100%">
<mx:Form>
<mx:FormItem label="Color">
<mx:ColorPicker  change="changeColorHandler(event)"  
selectedColor="#FF0000"/>
</mx:FormItem>
<mx:FormItem label="Velocity X">
<mx:NumericStepper value="1" maximum="10" minimum="0" 
change="changeVelocityX(event)"/>
</mx:FormItem>
<mx:FormItem label="Velocity Y">
<mx:NumericStepper value="1" maximum="10" minimum="0" 
change="changeVelocityY(event)"/>
</mx:FormItem>
<mx:FormItem label="Radius X">
<mx:NumericStepper value="100" maximum="100" minimum="1" 
change="changeRadiusX(event)"/>
</mx:FormItem>
<mx:FormItem label="Radius Y">
<mx:NumericStepper value="100" maximum="100" minimum="1" 
change="changeRadiusY(event)"/>
</mx:FormItem>
<mx:FormItem label="Alpha">
<mx:NumericStepper value="0.98" maximum="1" minimum="0" 
stepSize="0.01"  change="changeAlpha(event)" />
</mx:FormItem>
<mx:FormItem label="Radius">
<mx:NumericStepper value="2" maximum="5" minimum="1" 
change="changeRadius(event)" />
</mx:FormItem>
<mx:FormItem label="Clear">
<mx:Button label="Clear" click="clearImageHandler(event)" />
</mx:FormItem>
</mx:Form>  
</mx:Canvas>
<mx:VBox width="100%" height="100%" >   
<mx:Canvas id="myCanvas" width="100%" height="100%" 
creationComplete="initParticleHandler(event)"/>
<mx:Label text="www.developyourdream.net" />
</mx:VBox>

</mx:HBox>
</mx:Application>
In this case I used the circle formula of Sin and Cos and put some variable inside the formula, this is the basic formulas in X and Y that we are using:

X = sin( angle )* radius + initialPositionInX;
Y = cos( angle )* radius + initialPositionInY;

So we can do it with animation we need to change the angle, we what to go faster so we can put a velocity to the angle.
The formula that we are using with the variable expresses like this:

X = sin( time*velocityX )* radiusX + initialPositionInX;
Y = cos( time*velocityY )* radiusY + initialPositionInY;

We created a class called particle and used in the applications:
Particle Class
package
{
import mx.core.UIComponent;

public class Particle extends UIComponent
{

/*---------------------------------------------------------------------------*/
/*----------------------------- START VARIABLES -----------------------------*/
/*---------------------------------------------------------------------------*/ 

private var _particleColor:uint = 0x000000;
private var _particleSize:int = 2;

/*---------------------------------------------------------------------------*/
/*------------------------------ END VARIABLES ------------------------------*/
/*---------------------------------------------------------------------------*/ 

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*--------------------------- START INIT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/

public function Particle()
{
super();
}

/*---------------------------------------------------------------------------*/
/*---------------------------- END INIT FUNCTIONS ---------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*------------------------------ START GET SET ------------------------------*/
/*---------------------------------------------------------------------------*/

public function get particleColor():uint{
return _particleColor;
}
public function set particleColor(value:uint):void{
_particleColor = value;
invalidateDisplayList();
}

public function get particleSize():int{
return _particleSize;
}
public function set particleSize(value:int):void{
_particleSize = value;
invalidateDisplayList();
}

/*---------------------------------------------------------------------------*/
/*------------------------------- END GET SET -------------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*------------------------- START OVERRIDE FUNCTION -------------------------*/
/*---------------------------------------------------------------------------*/

override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number): void 
{
super.updateDisplayList(_particleSize,_particleSize);
graphics.clear();
graphics.lineStyle(1,_particleColor,1);
graphics.beginFill(_particleColor,1);
graphics.drawCircle(0,0,_particleSize);
graphics.endFill();
}

/*---------------------------------------------------------------------------*/
/*------------------------- END OVERRIDE FUNCTION ---------------------------*/
/*---------------------------------------------------------------------------*/

}
}

The Application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" frameRate="120" 
creationComplete="creationCompleteHandler(event)" layout="absolute" 
width="415" height="300" backgroundColor="0xFFFFFF"  xmlns:local="*" 
backgroundGradientAlphas="[1.0, 1.0]" 
backgroundGradientColors="[#FFFFFF, #FFFFFF]" themeColor="#FFFFFF" 
borderColor="#000000" borderStyle="solid" >
<mx:Script>
<![CDATA[
import mx.events.NumericStepperEvent;
import mx.events.ColorPickerEvent;
import mx.controls.Image;
import mx.core.UIComponent;
import mx.events.FlexEvent;

/*---------------------------------------------------------------------------*/
/*----------------------------- START VARIABLES -----------------------------*/
/*---------------------------------------------------------------------------*/ 

private var time:Number =0;
private var xo:Number = 0;
private var yo:Number = 0;
private var velocityX:Number = 1;
private var velocityY:Number = 1;
private var radiusX:Number = 100;
private var radiusY:Number = 100;
private var myCont:Canvas;
private var myImage:Image;
private var myParticle:Particle;

/*---------------------------------------------------------------------------*/
/*------------------------------ END VARIABLES ------------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*--------------------------- START INIT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/

private function creationCompleteHandler(event:FlexEvent):void{
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
private function initParticleHandler(event:FlexEvent):void{
myCont = new Canvas;
myCont.percentWidth = 100;
myCont.percentHeight = 100;
myCanvas.addChild(myCont);
myParticle = new Particle;
myParticle.particleSize = 2;
myParticle.particleColor = 0xFF0000;
xo = myParticle.x = myCanvas.width/2;
yo = myParticle.y = myCanvas.height/2;
myImage = new Image;
myImage.percentWidth = 100;
myImage.percentHeight = 100;
myImage.alpha = 0.98;
myCont.addChild(myImage);
myCont.addChild(myParticle);
}

/*---------------------------------------------------------------------------*/
/*---------------------------- END INIT FUNCTIONS ---------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*-------------------------- START EVENT FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/ 

/*-- START EVENT CAIRNGORM --*/

/*--- END EVENT CAIRNGORM ---*/

/***************************/

/*---- START EVENT FLEX -----*/
private function enterFrameHandler(event:Event):void{
time+=1/stage.frameRate;
myParticle.x = Math.sin(time*velocityX)*radiusX + xo; 
myParticle.y = Math.cos(time*velocityY)*radiusY + yo; 
myImage.source = new Bitmap(this.getUIComponentBitmapData(UIComponent(myCont)));
}
public function changeColorHandler(event:ColorPickerEvent):void{
myParticle.particleColor = event.color;
}
public function changeVelocityX(event:NumericStepperEvent):void{
velocityX = event.value;
}
public function changeVelocityY(event:NumericStepperEvent):void{
velocityY = event.value;
}
public function changeRadiusX(event:NumericStepperEvent):void{
radiusX = event.value;
}
public function changeRadiusY(event:NumericStepperEvent):void{
radiusY = event.value;
}
public function changeAlpha(event:NumericStepperEvent):void{
myImage.alpha = event.value;
}
public function changeRadius(event:NumericStepperEvent):void{
myParticle.particleSize = event.value;
}
public function clearImageHandler(event:MouseEvent):void{
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
myImage.source = new Bitmap();       
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}

/*----- END EVENT FLEX ------*/

/*---------------------------------------------------------------------------*/
/*-------------------------- END EVENT FUNCTIONS ----------------------------*/
/*---------------------------------------------------------------------------*/

/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*-------------------------- START OTHER FUNCTIONS --------------------------*/
/*---------------------------------------------------------------------------*/ 

public function getUIComponentBitmapData( target : UIComponent ) : BitmapData
{ 
var bd : BitmapData = new BitmapData( target.width, target.height );
var m : Matrix = new Matrix();
bd.draw( target, m );
return bd;  
}

/*---------------------------------------------------------------------------*/
/*-------------------------- END OTHER FUNCTIONS ----------------------------*/
/*---------------------------------------------------------------------------*/

]]>
</mx:Script>
<mx:HBox width="100%" height="100%">
<mx:Canvas width="78%" height="100%">
<mx:Form>
<mx:FormItem label="Color">
<mx:ColorPicker  change="changeColorHandler(event)"  
selectedColor="#FF0000"/>
</mx:FormItem>
<mx:FormItem label="Velocity X">
<mx:NumericStepper value="1" maximum="10" minimum="0" 
change="changeVelocityX(event)"/>
</mx:FormItem>
<mx:FormItem label="Velocity Y">
<mx:NumericStepper value="1" maximum="10" minimum="0" 
change="changeVelocityY(event)"/>
</mx:FormItem>
<mx:FormItem label="Radius X">
<mx:NumericStepper value="100" maximum="100" minimum="1" 
change="changeRadiusX(event)"/>
</mx:FormItem>
<mx:FormItem label="Radius Y">
<mx:NumericStepper value="100" maximum="100" minimum="1" 
change="changeRadiusY(event)"/>
</mx:FormItem>
<mx:FormItem label="Alpha">
<mx:NumericStepper value="0.98" maximum="1" minimum="0" 
stepSize="0.01"  change="changeAlpha(event)" />
</mx:FormItem>
<mx:FormItem label="Radius">
<mx:NumericStepper value="2" maximum="5" minimum="1" 
change="changeRadius(event)" />
</mx:FormItem>
<mx:FormItem label="Clear">
<mx:Button label="Clear" click="clearImageHandler(event)" />
</mx:FormItem>
</mx:Form>  
</mx:Canvas>
<mx:VBox width="100%" height="100%" >   
<mx:Canvas id="myCanvas" width="100%" height="100%" 
creationComplete="initParticleHandler(event)"/>
<mx:Label text="www.developyourdream.net" />
</mx:VBox>

</mx:HBox>
</mx:Application>



Descargar Archivo y Ver Codigo Fuente:


Download File's and Source: