package { /** * @author nicoptere */ import flash.display.*; import flash.events.*; public class Force extends Sprite { static public var STIFFNESS:Number = .01; public var X:Number; public var Y:Number; public var R:Number; public var A:Number; public var color:uint = 0x0000FF; //handle to rotate private var handle:Sprite; public function Force( X:Number, Y:Number ) { x = X; y = Y; handle = new Sprite(); handle.buttonMode = true; addChild( handle ); handle.addEventListener(MouseEvent.MOUSE_DOWN, startdrag ); handle.addEventListener(MouseEvent.MOUSE_UP, stopdrag ); } public function setup( X:Number, Y:Number ):void { var dx:Number = X - x; var dy:Number = Y - y; R = Math.sqrt( dx * dx + dy * dy ); A = Math.atan2( dy, dx ); this.X = dx; this.Y = dy; handle.x = dx; handle.y = dy; } public function startdrag( e:Event ):void { handle.startDrag(); handle.addEventListener(Event.ENTER_FRAME, enterFrameHandler); } public function stopdrag( e:Event ):void { handle.removeEventListener(Event.ENTER_FRAME, enterFrameHandler); } public function enterFrameHandler( e:Event ):void { setup( x + handle.x, y + handle.y); render(); } /* * */ public function process( vectors:Array ):void { var i:int; var v:Vector; var VL:uint = vectors.length; var maxSpeed:Number = Vector.MAX_SPEED; var friction:Number = VectorField.friction; for ( i = 0; i < VL; i++) { //for each vector in simulation v = vectors[ i ]; equation( v ); // applies some firction v.vx *= friction; v.vy *= friction v.x += v.vx; v.y += v.vy; //limiting the velocities to the Vector.MAX_SPEED value v.vx = ( v.vx > maxSpeed ) ? maxSpeed : ( v.vx < -maxSpeed ) ? -maxSpeed: v.vx; v.vy = ( v.vy > maxSpeed ) ? maxSpeed : ( v.vy < -maxSpeed ) ? -maxSpeed : v.vy; } } public function equation( v:Vector ):void { if( ( v.x < x + R ) && ( v.x > x - R ) && ( v.y < y + R ) && ( v.y > y - R ) ){ var dx:Number; var dy:Number; var dist:Number; //check the distance to emmitter dx = x - v.x; dy = y - v.y; dist = Math.sqrt( dx*dx + dy*dy ); //if the distance is inferior to the radius if( dist < R ) { //force adds its strength to alter the path v.vx += Math.cos( A ) * ( R - dist ) * STIFFNESS; v.vy += Math.sin( A ) * ( R - dist ) * STIFFNESS; } } } public function show():void { render(); handle.visible = true; } public function hide():void { graphics.clear(); handle.visible = false; } public function render():void { graphics.clear(); graphics.lineStyle( 1, color, .5 ); graphics.beginFill( color, .2 ); graphics.drawCircle( 0,0, R ); graphics.moveTo( 0,0 ); graphics.lineTo( X,Y ); handle.graphics.lineStyle( 2, color, .5); handle.graphics.beginFill( color, .5); handle.graphics.drawCircle( 0, 0, 4 ); } public function dispose():void { graphics.clear(); handle.removeEventListener(Event.ENTER_FRAME, enterFrameHandler); handle.removeEventListener(MouseEvent.MOUSE_DOWN, startdrag ); handle.removeEventListener(MouseEvent.MOUSE_UP, stopdrag ); removeChild( handle ); handle = null; } } }