package { import flash.display.BitmapData; /** * http://en.nicoptere.net/ * @author nicoptere */ public class ActivatorInhibitor { /** * constructor for the activator inhibitor system * @param width the width of the bitmapData * @param height the height of the bitmapData * @param alpha the alpha of the bitmapData */ public function ActivatorInhibitor( width:int = 8, height:int = 8, alpha:Boolean = false ) { _width = width; _height = height; _alpha = alpha; bd = new BitmapData( _width, _height, _alpha, 0x000000 ); } private var processing:Boolean = false; /** * solves the activator inhibitor system */ public function process():void { if ( processing ) return; processing = true; if ( cells == null ) reset(); var c:int; var total:int; var dist:Number; var i:int, x:int, y:int, dx:int, dy:int, ox:int, oy:int; var id:int; var cellsLength:int = cells.length; var minx:int, maxx:int, miny:int, maxy:int; var IR2:Number = _IR * _IR; var OR2:Number = _OR * _OR; for ( i = 0; i < cellsLength; i++ ) { ox = i % _width; oy = int( i / _width ); _A = 0; _I = 0; minx = ox - _OR; if ( minx < 0 ) minx = 0; maxx = ox + _OR; if ( maxx > _width ) maxx = _width; miny = oy - _OR; if ( miny < 0 ) miny = 0; maxy = oy + _OR; if ( maxy > _height ) maxy = _height; for ( x = minx; x < maxx; x++ ) { for ( y = miny; y < maxy; y++ ) { dx = ox - x; dy = oy - y; dist = ( dx * dx + dy * dy ); if ( dist > OR2 ) continue; //retrieves the current cell's value : // white = D = 1 // black = U = -1 if ( cells[ ( ( y * _width ) + x ) ] == 1 ) { c = 1; }else { c = -1; } //attraction if ( dist <= IR2 ) { _A += c; } else //inhibition { _I += c; } } } //magic total = ( _A * _J1 + _I * _J2 + _H ); if ( total < 0 ) cells[ i ] = 0; if ( total > 0 ) cells[ i ] = 1; } bd.fillRect( bd.rect, skinColor ); bd.lock(); for ( i = 0; i < cellsLength; i++ ) { bd.setPixel32( i % _width, int( i / _width ), cells[i] == 1 ? furColor : skinColor ); } bd.unlock(); processing = false; } /** * assigns the settings to the activator / inhibitor system * @param activate amount of activation 0 > 1 * @param inhibit amount of inhibition 0 > 1 * @param innerRadius size of the cell's inner radius > 0 * @param outerRadius size of the cell's outer radius > innerRadius * @param bias a number to smooth the influence of the activator ( 0 > 10 ) */ public function settings( activate:Number = .5 , inhibit:Number = -.5, innerRadius:int = 1, outerRadius:int = 3, bias:Number = 1 ):void { this.activate = activate; this.inhibit = inhibit; this.innerRadius = innerRadius; this.outerRadius = outerRadius; this.bias = bias; } /** * resets the activator inhibitor system to default */ public function reset():void { var i:int, total:int = _width * _height, col:uint; cells = new Vector.( total ); bd.lock(); for ( i = 0; i < total; i ++ ) { col = ( bd.getPixel( i % _width, int( i / _width ) ) <= 0x777777 ) ? 0x00000000 : 0xFF000000; bd.setPixel32( i % _width, int( i / _width ), col ) cells[ i ] = col ? 0 : 1; } bd.unlock(); } private var bd:BitmapData; public function set bitmapData(value:BitmapData):void { bd = value.clone(); } public function get bitmapData():BitmapData { return bd; } //bitmapData size private var _size:uint = 8; public function set size(value:uint):void { _size = _width = height = value; bd = new BitmapData( _width, _height, _alpha, 0x00000000 ); } public function get size():uint { return _size; } private var _width:uint = 8; public function set width(value:uint):void { _width = value; bd = new BitmapData( _width, _height, _alpha, 0x00000000 ); } public function get width():uint { return _width; } private var _height:uint = 8; public function set height(value:uint):void { _height = value; bd = new BitmapData( _width, _height, _alpha, 0x00000000 ); } public function get height():uint { return _height; } //activate / inhibit powers private var _J1:Number = .5; public function set activate(value:Number):void { _J1 = value; } public function get activate():Number { return _J1; } private var _J2:Number = -.5; public function set inhibit(value:Number):void { _J2 = value; } public function get inhibit():Number { return _J2; } //inner / outer radii private var _IR:Number = 1; public function set innerRadius(value:Number):void { _IR = value; } public function get innerRadius():Number { return _IR; } private var _OR:Number = 3; public function set outerRadius(value:Number):void { _OR = value; } public function get outerRadius():Number { return _OR; } //bias private var _H:Number = 5; public function set bias(value:Number):void { _H = value; } public function get bias():Number { return _H; } //colors private var _furcolor:uint = 0xe7deb5; public function set furColor(value:uint):void { _furcolor = value; } public function get furColor():uint { return _furcolor; } private var _skincolor:uint = 0x291010; public function set skinColor(value:uint):void { _skincolor = value; } public function get skinColor():uint { return _skincolor; } //activate / inhibit totals private var _A:Number = 0; private var _I:Number = 0; private var cells:Vector.; private var _alpha:Boolean; } }