In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Drawing Force Field

/**
 * Copyright WLAD ( http://wonderfl.net/user/WLAD )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jLRD
 */

package {
    import com.bit101.components.HUISlider;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.utils.getTimer;
    
    public class Temp extends Sprite {
        
        private var field:ForceField;
        private var display:DisplayForceField;
        
        public function Temp() 
        {
            initBg();
            
            field = new ForceField();
            field.add( 100, 100, -30);
            field.add( 0, 0, 10);
            
            display = new DisplayForceField( 70, 70, 0xFF7979, 0x79BCFF);
            addChild(display);
            
            addEventListener(Event.ENTER_FRAME, update);
            
            with ( new HUISlider(this, 5, 5, "A", function(e:*= null):void
            {
                field.forces[0].charge = e.target.value;
            })) {
                minimum = -50;
                maximum = 50;
                value = field.forces[0].charge;
            }
            with ( new HUISlider(this, 200, 5, "B", function(e:*= null):void
            {
                field.forces[1].charge = e.target.value;
            })) {
                minimum = -50;
                maximum = 50;
                value = field.forces[1].charge;
            }
        }
        
        private function initBg():void 
        {
            var bg:Shape = new Shape();
            addChild( bg );
            bg.graphics.beginFill( 0 );
            bg.graphics.drawRect(00, 0, SW, SH);
            bg.graphics.endFill();
        }
        
        private function update(e:Event):void 
        {
            field.forces[0].x = display.mouseX;
            field.forces[0].y = display.mouseY;
            
            display.draw( field );
        }
    }
}

import flash.display.Shape;
import flash.geom.Point;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.text.TextField;

var SW:int = 465, SH:int = 465;

class DisplayForceField extends Shape
{
    private var w:int;
    private var h:int;
    private var r:int;
    private var color:uint;
    private var ah:int;
    private var aw:int;
    private var colorN:uint;
    private var colorP:uint;
    
    public function DisplayForceField( w:int = 30, h:int = 30, colorP:uint = 0xFF0000 , colorN:uint = 0x0000FF)
    {
        this.colorP = colorP;
        this.colorN = colorN;
        this.h = h;
        this.w = w;
        
        aw = int( SW / w );
        ah = int( SH / h );
        
        x = SW / 2;
        y = SH / 2;
        
        r = ( aw < ah ? aw : ah ) / 2 ;
    }
    
    public function draw( ff:ForceField ):void
    {
        graphics.clear();
        
        var v:Vec;
        var f:Force = new Force( 0, 0, 1);
        
        // remeber - since the FF is shifter to x=Sw/2, y=Sh/2 
        // the origin is located in X=0, and Y=0
        
        var a:Number; var c:uint;
        
        for (var x:int = -w/2; x < w/2; x++)
        {
            for (var y:int = -h/2; y < h/2; y++)
            {
                f.x = aw * x;
                f.y = aw * y;
                
                // Find out the force of resolute at force 'f' position 
                v = ff.f( f.x, f.y , f.charge );
                
                a = 100 / v.lenght;

                c = blend( colorP, colorN , (ff.forceT * 100) + 0.5 );
                
                // trace( ff.forceT );
                
                graphics.lineStyle( r , c , a );
                
                if ( ff.forceT < 0 )
                {
                    v.x = -v.x;
                    v.y = -v.y;
                }
                
                drawArrow( f, v );
            }
        }
        
        for (var i:int = 0; i < ff.forces.length; i++)
        {
            c = ff.forces[i].charge > 0 ? colorP : colorN;
            
            graphics.lineStyle( r, 0x333333 );
            graphics.beginFill( c );
            graphics.drawCircle( ff.forces[i].x, ff.forces[i].y, 10 );
            graphics.endFill();
        }
    }
    
    private function drawArrow( f:Force, v:Vec ):void
    {
        v.lenght = r ;
        
        graphics.moveTo( f.x + v.x , f.y + v.y );
        graphics.lineTo( f.x, f.y );
    }
}

class ForceField 
{
    public static var CONST:Number = 1;
    
    public var forces:Vector.<Force>;
    
    public function ForceField( )
    {
        forces = new Vector.<Force>();
    }
    
    public function add( x:Number, y:Number, charge:Number ):void
    {
        forces.push( new Force( x, y, charge ) );
    }
    
    public function f( x:Number, y:Number, q:Number ):Vec
    {
        var totalForce:Vec = new Vec();
        
        // E = F / q
        
        // E = kQ / r^2
        
        // F = Eq = kQq / r^2
        
        // q = 1
        
        // F = kQ / r^2
        
        // C = F = kQ / r ^ 2
        
        // A^2 + B^2 = C^2
        
        //     /|
        //  C / |
        //   /  | B ( y )
        //  /a  |
        // ------
        //   A ( x )
        
        // cos = x / C
        // sin = y / C
        
        // x = cos * C
        // y = sin * C
        
        var nx:Number, ny:Number, 
        
        sin:Number, cos:Number, 
        
        r2:Number, force:Number, f2:Force;
        
        forceT = 0;
        
        for ( var i:int = 0; i < forces.length; i++)
        {
            f2 = forces[ i ];
            
            nx = ( f2.x - x );
            ny = ( f2.y - y );
            
            r2 = nx * nx + ny * ny;
            
            force = ( CONST * f2.charge * q ) / r2; 
            
            forceT += force;
            
            // out( force );
            
            r2 = Math.sqrt(r2);
            
            cos = nx / r2;
            sin = ny / r2;
            
            totalForce.x += cos * r2;
            totalForce.y += sin * r2;
        }
        
        return totalForce;
    }
    
    /// Read after calling f( ... )
    public var forceT:Number = 0;
}

class Force extends Point
{
    public var charge:Number;
    
    public function Force( x:Number = 0, y:Number = 0, charge:Number = 0)
    {
        super( x, y );
        
        this.charge = charge;
    }
}

/**
 * ...
 * @author vladik.voina@gmail.com
 */
class Vec
{
    /**    rotates one vector around point by x radians and returns a Vec class.
     * @param vec [Vec] The vector that beening rotated.
     * @param around [Vec] The rotation point that the vector is rotated.
     * @param angle [Number] The angle in radians.
     **/
    public static function rotate(vec:Vec, around:Vec, angle:Number):Vec
    {
        var v:Vec = vec.vecMinus(around);
        
        v.radians += angle;
        v.plus(around);
        
        return v;
    }
    
    public static function Polar(lenght:Number, radians:Number):Vec
    {
        return new Vec(lenght * Math.cos( radians ),lenght * Math.sin( radians ) );
    }
    public static function Polar2(lenght:Number, degrees:Number):Vec
    {
        return new Vec(lenght * Math.cos( degrees * Math.PI / 180 ),lenght * Math.sin( degrees * Math.PI / 180 ) );
    }
    static public function vectorBetween(v1:Vec, v2:Vec):Vec
    {
        return new Vec(Math.max(v1.x, v2.x) - Math.min(v1.x, v2.x), Math.max(v1.y, v2.y) - Math.min(v1.y, v2.y));
    }
    public static function fromPoint(p:Point):Vec
    {
        return new Vec(p.x, p.y);
    }
    static public function from2Point(start:Point, end:Point):Vec 
    {
        return new Vec(end.x - start.x, end.y - start.y);
    }
    
    
    public var x:Number, y:Number;
    
    public function Vec(x:Number = 0,y:Number = 0) 
    {
        this.x = x;
        this.y = y;
    }
    public function get lenght():Number
    {
        return Math.sqrt(x * x + y * y);
    }
    public function set lenght(value:Number):void 
    {
        if (lenght == 0) scale(0);
        else scale(value / lenght);
    }
    public function set degrees(value:Number):void 
    {
        radians = value * Math.PI / 180;
    }
    public function get degrees():Number
    {
        return radians * 180 / Math.PI;
    }
    public function set radians(value:Number):void 
    {
        var f:Number = lenght;
        x = Math.cos(value) * f;
        y =  Math.sin(value) * f;
    }
    public function get radians():Number 
    {
        return Math.atan2(y, x);
    }
    public function get sin():Number
    {
        var f:Number = lenght;
        if (f != 0) return y / f;
        return 0;
    }
    public function set sin(value:Number):void
    {
        radians = Math.asin(value);
    }
    public function get cos():Number
    {
        var f:Number = lenght;
        if (f != 0) return x / f;
        return 0;
    }
    public function set cos(value:Number):void
    {
        radians = Math.acos(value);
    }
    public function dot(v:Vec):Number
    {
        return this.x * v.x + this.y * v.y;
    }
    public function plus(vec:Vec):void 
    {
        x += vec.x;
        y += vec.y;
    }
    public function minus(vec:Vec):void 
    {
        x -= vec.x;
        y -= vec.y;
    }
    public function mult(vec:Vec):void 
    {
        x *= vec.x;
        y *= vec.y;
    }
    public function scale(n:Number):void
    {
        x *= n;
        y *= n;
    }
    //Divisoin.
    public function divi(vec:Vec):void 
    {
        if (vec.x != 0 && vec.y != 0)
        {
            x /= vec.x;
            y /= vec.y;
        }
    }
    public function copy(vec:Vec):void 
    {
        x = vec.x;
        y = vec.y;
    }
    public function rotateAroundVector(vec:Vec,radians:Number):Vec
    {
        this.radians += radians;
        plus(vec);
        return this;
    }
    public function vecRotateAroundVector(vec:Vec,radians:Number):Vec
    {
        return clone().rotateAroundVector(vec,radians);
    }
    public function vecPlus(vec:Vec):Vec
    {
        return new Vec(x + vec.x, y + vec.y);
    }
    public function vecMinus(vec:Vec):Vec
    {
        return new Vec(x - vec.x, y - vec.y);
    }
    public function vecMult(vec:Vec):Vec 
    {
        return new Vec(x * vec.x, y * vec.y);
    }
    public function vecDivi(vec:Vec):Vec 
    {
        return new Vec(x * vec.x, y * vec.y);
    }
    public function vecForce(force:Number):Vec
    {
        return new Vec(x * (force / this.lenght), y * (force / this.lenght));
    }
    public function normR():Vec
    {
        return new Vec(-y,x);
    }
    public function normL():Vec
    {
        return new Vec(y,-x);
    }
    public function normalize():void
    {
        var f:Number = lenght;
        if (f != 0)
        {
            x /= f;
            y /= f;
        }
    }
    public function normalizedVec():Vec
    {
        return new Vec(x / lenght,y / lenght);
    }
    public function clone():Vec
    {
        return(new Vec(x, y));
    }
    public function toPoint():Point
    {
        return new Point(x, y);
    }
    public function toString():String 
    {
        return "< X: " + x + " >,< Y: " + y + " >.";
    }
    public function draw(g:Graphics, startPos:Point = null, scale:Number = 5, center:Boolean = false ):void
    {
        if (startPos == null) startPos = new Point(0, 0);
        var hx:Number = x / 2;
        var hy:Number = y / 2;
        var sx:Number = startPos.x + ( center ? hx : 0 );
        var sy:Number = startPos.y + ( center ? hy : 0 );
        var ex:Number = sx + ( center ? hx : x );
        var ey:Number = sy + ( center ? hy : y );
        g.moveTo( sx , sy );
        g.lineTo( ex , ey );
        var vr:Vec = normR();
        var vl:Vec = normL();
        // x / l * s = (x/l) * s = s( x/l ) = (s*x) / l = ( s / l ) * x
        // ... = s / l * x
        var svr:Number = scale / vr.lenght;
        g.lineTo
        ( 
            ex - svr * ( x - vr.x ),
            ey - svr * ( y - vr.y )
        );
        g.moveTo( ex , ey );
        g.lineTo
        ( 
            ex - svr * ( x - vl.x ),
            ey - svr * ( y - vl.y )
        );
    }
    
    public function opMultiply(value:Number):void 
    {
        x *= value;
        y *= value;
    }
    
    public function opSubtract(value:Number):void
    {
        x -= value;
        y -= value;
    }
    
    public function opDivide(value:Number):void
    {
        var v:Number = (value == 0) ? 0.00001 : value;
        x /= v;
        y /= v;
    }
}
/**
* Blends two colours. Percentage should be 0.5 for an equal blend.
*/
function blend(first:uint, second:uint, percent:Number):uint
{
    var r:int = ((first & 0xff0000) >> 16) * (1 - percent) + ((second & 0xff0000) >> 16) * percent;
    var g:int = ((first & 0x00ff00) >> 8) * (1 - percent) + ((second & 0x00ff00) >> 8) * percent;
    var b:int = ((first & 0x0000ff) ) * (1 - percent) + ((second & 0x0000ff) ) * percent;

    return r << 16 | g << 8 | b;
}