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

荷電粒子の運動

磁場(緑)、電場(橙)中での正電荷を帯びた粒子の運動のシミュレーションです。
磁場中では等速円運動、電場中では等加速度運動を行います。
Get Adobe Flash player
by Nicolas 15 Feb 2015
/**
 * Copyright Nicolas ( http://wonderfl.net/user/Nicolas )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ryvc
 */

// forked from Nicolas's forked from: ラザフォードの実験
// forked from Nicolas's ラザフォードの実験
// forked from Nicolas's パーティクル
package {
    import flash.text.TextField;
    import flash.geom.Rectangle;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.events.*;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import net.hires.debug.Stats;
    
    [SWF(frameRate="60")]
    public class LCForce extends Sprite 
    {
        private const WIDTH:int = 465;
        private const HEIGHT:int = 465;
        private var bmp:Bitmap;
        private var bmd:BitmapData;
        private var updater:LCForceUpdater;
        private var renderer:Renderer;
        private var poolSize:int = 1000;
        private var pool:ParticlePool;
        private var count:int = 0;
        
        
        public function LCForce() 
        {
            bmd = new BitmapData(WIDTH, HEIGHT, false, 0x000000);
            bmp = addChild(new Bitmap(bmd)) as Bitmap;
            ParticlePool.setPoolSize(poolSize);
            pool = ParticlePool.getInstance();
                     
            var sp:Sprite = new Sprite();
            sp.graphics.beginFill(0x00FF00, 0.3);
            sp.graphics.drawRect(300,0,150,500);
            addChild(sp);    
            var text:TextField = new TextField();
            text.text = "B";
            text.textColor = 0xFFFFFF;
            text.x = 370;
            text.y = 20;
            text.scaleX = text.scaleY = 1.5;
            addChild(text);
            var bMark:Shape = new Shape();
            bMark.graphics.lineStyle(2, 0xFFFFFF);
            bMark.graphics.moveTo(-10, 0);
            bMark.graphics.lineTo(10, 0);
            bMark.graphics.moveTo(0, -10);
            bMark.graphics.lineTo(0, 10);
            bMark.graphics.drawCircle(0, 0, 10);
            bMark.rotation = 45;
            bMark.x = 400;
            bMark.y = 20;
            addChild(bMark);
            var field:Field = new Field(0, 0, 0.3, sp);
            
            var sp2:Sprite = new Sprite();
            sp2.graphics.beginFill(0x00FF00, 0.3);
            sp2.graphics.drawRect(0,0,150,300);
            addChild(sp2);
            var text2:TextField = new TextField();
            text2.text = "B";
            text2.textColor = 0xFFFFFF;
            text2.x = 70;
            text2.y = 20;
            text2.scaleX = text2.scaleY = 1.5;
            addChild(text2);
            var bMark2:Shape = new Shape();
            bMark2.graphics.lineStyle(2, 0xFFFFFF);
            bMark2.graphics.beginFill(0xFFFFFF);
            bMark2.graphics.drawCircle(0, 0, 3);
            bMark2.graphics.endFill();
            bMark2.graphics.drawCircle(0, 0, 10);
            bMark2.x = 100;
            bMark2.y = 20;
            addChild(bMark2);
            var field2:Field = new Field(0, 0, -0.5, sp2);
            
            var sp3:Sprite = new Sprite();
            sp3.graphics.beginFill(0xFFDD00, 0.3);
            sp3.graphics.drawRect(150,0,150,500);
            addChild(sp3);
            var text3:TextField = new TextField();
            text3.text = "E";
            text3.textColor = 0xFFFFFF;
            text3.x = 220;
            text3.y = 20;
            text3.scaleX = text3.scaleY = 1.5;
            addChild(text3);
            var eMark:Shape = new Shape();
            eMark.graphics.lineStyle(2, 0xFFFFFF);
            eMark.graphics.moveTo(-10, 0);
            eMark.graphics.lineTo(10, 0);
            eMark.graphics.moveTo(5, -5);
            eMark.graphics.lineTo(10, 0);
            eMark.graphics.lineTo(5, 5);
            eMark.x = 250;
            eMark.y = 20;
            addChild(eMark);
            var field3:Field = new Field(3, 0, 0, sp3);
            
            updater = new LCForceUpdater(WIDTH, HEIGHT);
            updater.fields.push(field, field2, field3);
            renderer = new Renderer(bmd);
                       
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
                buttonDown = true;  
            });
            stage.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
                  buttonDown = false;
            });
  
            
            //addChild(new Stats());
        }
        
        private var buttonDown:Boolean = false;
        private function enterFrameHandler(e:Event):void
        {
            if(buttonDown) {
                var p:Particle = pool.acquire();
                p.x = mouseX;
                p.y = mouseY;
                p.vx = 20;
                p.vy = 0;
            }
            updater.update();
            renderer.render();
            //count++;
        }

    }
}
import flash.geom.Vector3D;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
import flash.display.BitmapData;

class Renderer 
{
    private var targetBmd:BitmapData
    private var rect:Rectangle;
    private var colorTransform:ColorTransform;
    private var pool:ParticlePool;
    private var particleRect:Rectangle = new Rectangle(0, 0, 3, 3);
    
    public function Renderer(bmd:BitmapData)
    {
        targetBmd = bmd;
        rect = targetBmd.rect;
        colorTransform = new ColorTransform(0.9, 0.9, 0.9);
        pool = ParticlePool.getInstance();
    }

    public function render():void
    {
        targetBmd.lock();
        targetBmd.colorTransform(targetBmd.rect, colorTransform);
        var len:int = pool.livingParticles.length;
        var p:Particle;
        for (var i:int = 0; i < len; i++)
        {
            p = pool.livingParticles[i];
            //targetBmd.setPixel(p.x, p.y, 0xFFFFFF);
            particleRect.x = p.x - 1;
            particleRect.y = p.y - 1;
            targetBmd.fillRect(particleRect, 0xFFFFFF);
        }
        
        targetBmd.unlock();
    }

}

class Updater
{
    private var bmdWidth:int;
    private var bmdHeight:int;
    protected var pool:ParticlePool;
    public var t:Number = 0;
    public var dt:Number = 0.1;
    
    //temp
    private var x:Number = 0;
    private var y:Number = 0;
    private var vx:Number = 0;
    private var vy:Number = 0;
    
    
    public function Updater(width:int, height:int)
    {
        bmdWidth = width;
        bmdHeight = height;
        pool = ParticlePool.getInstance();
    }
    
    public function update():void
    {
        var len:int = pool.livingParticles.length;
        var p:Particle;
        for (var i:int = 0; i < len; i++)
        {
            p = pool.livingParticles[i];
            this.x = p.x;
            this.y = p.y;
            this.vx = p.vx;
            this.vy = p.vy;
            
            //4次のルンゲクッタ法を、x,y,vx,vyについて連立
            var k1:Vector.<Number> = new Vector.<Number>(4);
            var k2:Vector.<Number> = new Vector.<Number>(4);
            var k3:Vector.<Number> = new Vector.<Number>(4);
            var k4:Vector.<Number> = new Vector.<Number>(4);
            
            k1[0] = dt * fx(t, x, y, vx, vy);
            k1[1] = dt * fy(t, x, y, vx, vy);
            k1[2] = dt * fvx(t, x, y, vx, vy);
            k1[3] = dt * fvy(t, x, y, vx, vy);
            
            k2[0] = dt * fx(t + dt / 2, x + k1[0] / 2, y + k1[1] / 2, vx + k1[2] / 2, vy + k1[3] / 2);
            k2[1] = dt * fy(t + dt / 2, x + k1[0] / 2, y + k1[1] / 2, vx + k1[2] / 2, vy + k1[3] / 2);
            k2[2] = dt * fvx(t + dt / 2, x + k1[0] / 2, y + k1[1] / 2, vx + k1[2] / 2, vy + k1[3] / 2);
            k2[3] = dt * fvy(t + dt / 2, x + k1[0] / 2, y + k1[1] / 2, vx + k1[2] / 2, vy + k1[3] / 2);
            
            k3[0] = dt * fx(t + dt / 2, x + k2[0] / 2, y + k2[1] / 2, vx + k2[2] / 2, vy + k2[3] / 2);
            k3[1] = dt * fy(t + dt / 2, x + k2[0] / 2, y + k2[1] / 2, vx + k2[2] / 2, vy + k2[3] / 2);
            k3[2] = dt * fvx(t + dt / 2, x + k2[0] / 2, y + k2[1] / 2, vx + k2[2] / 2, vy + k2[3] / 2);
            k3[3] = dt * fvy(t + dt / 2, x + k2[0] / 2, y + k2[1] / 2, vx + k2[2] / 2, vy + k2[3] / 2);
            
            k4[0] = dt * fx(t + dt, x + k3[0], y + k3[1], vx + k3[2], vy + k3[3]);
            k4[1] = dt * fy(t + dt, x + k3[0], y + k3[1], vx + k3[2], vy + k3[3]);
            k4[2] = dt * fvx(t + dt, x + k3[0], y + k3[1], vx + k3[2], vy + k3[3]);
            k4[3] = dt * fvy(t + dt, x + k3[0], y + k3[1], vx + k3[2], vy + k3[3]);
            
            p.x += (k1[0] + k2[0] * 2 + k3[0] * 2 + k4[0]) / 6;
            p.y += (k1[1] + k2[1] * 2 + k3[1] * 2 + k4[1]) / 6;
            p.vx += (k1[2] + k2[2] * 2 + k3[2] * 2 + k4[2]) / 6;
            p.vy += (k1[3] + k2[3] * 2 + k3[3] * 2 + k4[3]) / 6;
            
            
            if(p.x < 0 || p.x > bmdWidth || p.y < 0 || p.y > bmdHeight)
            {
               pool.release(p);
               len--;
            }

        }
        
    }
    
        public function fx(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number
    {
        return 0;
    }
    
    public function fy(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number
    {
        return 0;
    }
    
    public function fvx(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number
    {
        return 0;
    }
    
    public function fvy(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number
    {
        return 0;
    }

}

import flash.display.Sprite;
class LCForceUpdater extends Updater
{
    public var fields:Vector.<Field>;
    
    public function LCForceUpdater(width:int, height:int)    
    {
        super(width, height);
        fields = new Vector.<Field>();
    }
        
    override public function fx(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number 
    {
        return vx;
    }
    
    override public function fy(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number 
    {
        return vy;
    }
    
    override public function fvx(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number 
    {
        var dst:Number = 0;
        var numFields:int = fields.length;
        for (var i:int = 0; i < numFields; i++) {
            if(fields[i].area.hitTestPoint(x, y, true)){
                dst += vy * fields[i].B + fields[i].Ex;
            }
        }
        return dst;
    }
    
    override public function fvy(t:Number, x:Number, y:Number, vx:Number, vy:Number):Number 
    {
        var dst:Number = 0;
        var numFields:int = fields.length;
        for (var i:int = 0; i < numFields; i++) {
            if(fields[i].area.hitTestPoint(x, y, true)){
                dst += - vx * fields[i].B + fields[i].Ey;
            }
        }
        return dst;
    }
}

class Field
{
    public var Ex:Number;
    public var Ey:Number;
    public var B:Number;
    public var area:Sprite;
    public function Field(Ex:Number, Ey:Number, B:Number, area:Sprite)
    {
        this.Ex = Ex;
        this.Ey = Ey;
        this.B = B;
        this.area = area;
    }
}

class Particle 
{
    public var x:Number;
    public var y:Number;
    public var vx:Number;
    public var vy:Number;
    
    public function Particle()
    {
    
    }
    
}

class NullParticle extends Particle
{
    private static var _instance:NullParticle;
        
    public function NullParticle(s:SingletonEnforcer) 
    {
        if (!s) throw new Error("Singleton Error");
    }
         
    public static function getInstance():NullParticle
    {
        if (!_instance) return new NullParticle(new SingletonEnforcer());
        else return _instance;
    }
}

class ParticlePool 
{
    private static var _instance:ParticlePool;
    private static var _poolSize:int;
    private var _livingParticles:Vector.<Particle>;
    private var _deadParticles:Vector.<Particle>;
    
    public function ParticlePool(s:SingletonEnforcer)
    {
        if (!s) throw new Error("Singleton Error");
        _deadParticles = new Vector.<Particle>();
        for (var i:int = 0; i < _poolSize; i++)
        {
            _deadParticles[i] = new Particle();
        }
        _livingParticles = new Vector.<Particle>();
    }
    
    public static function setPoolSize(n:int):void
    {
        if (!_instance) _poolSize = n;
        else throw new Error("setPoolSize() must be used before creating ParticlePool instance");
    }
    
    public static function getInstance():ParticlePool 
    {
        if (!_instance) _instance = new ParticlePool(new SingletonEnforcer());
        return _instance;
    }
    public function acquire():Particle
    {
        var p:Particle;
        if (_deadParticles.length > 0) {
            p = _deadParticles.pop();
            _livingParticles.push(p);
        }
        else p = NullParticle.getInstance();
        return p;
    }
        
    public function release(p:Particle):void
    {
        var index:int = _livingParticles.indexOf(p);
        _livingParticles.splice(index, 1);
        _deadParticles.push(p);
    }
        
    public function get livingParticles():Vector.<Particle> { return _livingParticles; }
}

class SingletonEnforcer {}