Reaction-Diffusion Model

by greentec
Reference : http://www.karlsims.com/rd.html

* caution : very slow.
♥0 | Line 161 | Modified 2016-12-02 15:02:36 | MIT License
play

ActionScript3 source code

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

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    
    /**
     * ...
     * @author ypc
     */
    [SWF(width = 465, height = 465)]
    public class Main extends Sprite 
    {
        public var _width:int = 465;
        public var _height:int = 465;
        
        public var a:Vector.<Vector.<Number>>;
        public var b:Vector.<Vector.<Number>>;
        public var ca:Vector.<Vector.<Number>>;
        public var cb:Vector.<Vector.<Number>>;
        
        
        public var bitmapData:BitmapData;
        
        public function Main() 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            stage.frameRate = 60;
            
            bitmapData = new BitmapData(_width, _height, false, 0x0);
            var bitmap:Bitmap = new Bitmap(bitmapData);
            //bitmap.scaleX = bitmap.scaleY = 2;
            
            addChild(bitmap);
            
            initArray();
            
            addEventListener(Event.ENTER_FRAME, onLoop);
        }
        
        private function initArray():void
        {
            var i:int;
            var j:int;
            
            a = new Vector.<Vector.<Number>>(_height);
            b = new Vector.<Vector.<Number>>(_height);
            ca = new Vector.<Vector.<Number>>(_height);
            cb = new Vector.<Vector.<Number>>(_height);
            
            for (j = 0; j < _height; j += 1)
            {
                a[j] = new Vector.<Number>(_width);
                b[j] = new Vector.<Number>(_width);
                ca[j] = new Vector.<Number>(_width);
                cb[j] = new Vector.<Number>(_width);
                
                for (i = 0; i < _width; i += 1)
                {
                    a[j][i] = 1.0;
                    b[j][i] = 0.0;
                    
                    //if (i < _width / 2)
                    //{
                        //b[j][i] = 1.0;
                    //}
                    ca[j][i] = 0.0;
                    cb[j][i] = 0.0;
                }
            }
            
            var k:int = 5;
            for (j = int(_height / 2) - k; j <= int(_height / 2) + k; j += 1)
            {
                for (i = int(_width / 2) - k; i <= int(_width / 2) + k; i += 1)
                {
                    b[j][i] = 1.0;
                    a[j][i] = 0;
                }
            }
            
            
        }
        
        private function onLoop(e:Event):void
        {
            var i:int;
            //for (i = 0; i < 5; i += 1)
            {
                simulate();
            }
            drawScreen();
        }
        
        private function simulate():void
        {
            var i:int;
            var j:int;
            
            var la:Number; //laplacian
            var lb:Number;
            
            var Da:Number = 1.0;
            var Db:Number = .5;
            var f:Number = .0545//.0367//.055;
            var k:Number = .062//.0649//.062;
            
            var step:Number = 1;
            
            for (j = 0; j < _height; j += 1)
            {
                for (i = 0; i < _width; i += 1)
                {
                    la = -a[j][i];
                    lb = -b[j][i];
                    
                    if (i > 0)
                    {
                        la += .2 * a[j][i - 1];
                        lb += .2 * b[j][i - 1];
                        
                        if (j > 0)
                        {
                            la += .05 * a[j - 1][i - 1];
                            lb += .05 * b[j - 1][i - 1];
                        }
                        if (j < _height - 1)
                        {
                            la += .05 * a[j + 1][i - 1];
                            lb += .05 * b[j + 1][i - 1];
                        }
                    }
                    if (i < _width - 1)
                    {
                        la += .2 * a[j][i + 1];
                        lb += .2 * b[j][i + 1];
                        
                        if (j > 0)
                        {
                            la += .05 * a[j - 1][i + 1];
                            lb += .05 * b[j - 1][i + 1];
                        }
                        if (j < _height - 1)
                        {
                            la += .05 * a[j + 1][i + 1];
                            lb += .05 * b[j + 1][i + 1];
                        }
                    }
                    
                    if (j > 0)
                    {
                        la += .2 * a[j - 1][i];
                        lb += .2 * b[j - 1][i];
                    }
                    if (j < _height - 1)
                    {
                        la += .2 * a[j + 1][i];
                        lb += .2 * b[j + 1][i];
                    }
                    
                    
                    ca[j][i] = a[j][i] + (Da * la - a[j][i] * b[j][i] * b[j][i] + f * (1 - a[j][i])) * step;
                    cb[j][i] = b[j][i] + (Db * lb + a[j][i] * b[j][i] * b[j][i] - (k + f) * b[j][i]) * step;
                }
            }
            
            
            for (j = 0; j < _height; j += 1)
            {
                for (i = 0; i < _width; i += 1)
                {
                    a[j][i] = ca[j][i];
                    b[j][i] = cb[j][i];
                }
            }
        }
        
        private function drawScreen():void
        {
            var i:int;
            var j:int;
            var color:uint;
            
            bitmapData.fillRect(bitmapData.rect, 0x0);
            
            bitmapData.lock();
            
            for (j = 0; j < _height; j += 1)
            {
                for (i = 0; i < _width; i += 1)
                {
                    //color = (b[j][i] * 255) << 16 | (a[j][i] * 255); 
                    color = b[j][i] * 255;
                    color = color << 16 | color << 8 | color;
                    
                    bitmapData.setPixel(i, j, color);
                }
            }
            
            bitmapData.unlock();
        }
        
    }
    
}