package { /** * Flash/actionscript class for Belousov-Zhabotinsky- cellular automata * Petri Leskinen, 1st July 2009 * in Espoo, Finland */ import flash.display.BitmapData; import flash.display.GraphicsPathWinding; import flash.geom.Point; public class BelousovZhabotinskyCA extends BitmapData { public var q:int = 250, // q = the number of different possible cells k1:int = 2, k2:int = 8, g:int = 32; // see function grow for further info // I've notices works best with values when g*k2 is near q // flamy: 250, 2, 8, 32 // a cell has a value between 0 and q // for the image, cells are copied to bitmapdata (this) and toned with mapPalette public var cells:Vector.; private var _color0:uint = 0x103300, _color1:uint = 0xFFFFCC; private var i:int, j:int, palette:Array; public function BelousovZhabotinskyCA(_w:int=100, _h:int =100, _k1:int=2, _k2:int=6, _g:int=40) { super(_w,_h,false,0x00); k1= _k1; k2= _k2; g = _g; setPalette(); init(); } public function init():void { this.noise(int(20*Math.random()), 0, q, 4, false); updateCells(); } public function updateCells():void { cells = this.getVector(this.rect); for (i = 0; i != cells.length; ++i) cells[i] = cells[i] & 0xFF; } public function grow(loops:int=1):void { /* principles: * (i) If the cell is healthy (i.e., in state 0) then its new state is [a/k1] + [b/k2], * where a is the number of infected cells among its eight neighbors, * b is the number of ill cells among its neighbors, and k1 and k2 are constants. * Here "[]" means the integer part of the number enclosed, so that, for example, [7/3] = [2+1/3] = 2. (ii) If the cell is ill (i.e., in state n) then it miraculously becomes healthy (i.e., its state becomes 0). (iii) If the cell is infected (i.e., in a state other than 0 and n) then its new state is [s/(a+b+1)] + g, where a and b are as above, s is the sum of the cells of the cell and of its neighbors and g is a constant. */ var w:int = width, h:int = height, a:int, b:int, s:int, pxl:int, wh:int = w * h, i0:int, i2:int, j0:int, j2:int, ii:int; for (var k:int = 0; k != loops; ++k) { var newcells:Vector. = new Vector.(wh, true); ii = 0; for (j0= wh-w, j = 0, j2=w; j != wh; j+=w ) { for (i0=w-1, i = 0, i2= 1; i != w; ++i) { a = 0; b = 0; // going through neighbor cells: if ((pxl = cells[i0+j0]) == q) ++b else if (pxl) ++a; s = pxl; if ((pxl = cells[i+j0]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i2+j0]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i0+j]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i2+j]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i0+j2]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i+j2]) == q) ++b else if (pxl) ++a; s += pxl; if ((pxl = cells[i2+j2]) == q) ++b else if (pxl) ++a; s += pxl; switch (cells[ii]) { case 0: newcells[ii] = int(a / k1) + int(b / k2); break; case q: newcells[ii] = 0; break; default: s += (pxl=cells[ii]); pxl = (s / (a + b + 1)) + g; if (pxl > q) pxl = q; newcells[ii] = pxl; } ++ii; if (++i0 == w) i0 = 0; if (++i2 == w) i2 = 0; } if ((j0+=w) == wh) j0 = 0; if ((j2+=w) == wh) j2 = 0; } cells = newcells; } lock(); setVector(rect, newcells); // 0<= cell <= 250 : paletteMap by blue channel paletteMap(this, rect, new Point(), [], [], palette); unlock(); } public function set color0 (value:uint):void { _color0 = value; setPalette(); } public function get color0 ():uint { return _color0; } public function set color1 (value:uint):void { _color1 = value; setPalette(); } public function get color1 ():uint { return _color1; } private function setPalette():void { palette = []; var red0:uint = _color0 & 0xFF0000, red1:int = (_color1 & 0xFF0000) - red0, green0:uint = _color0 & 0xFF00, green1:int = (_color1 & 0xFF00) - green0, blue0:uint = _color0 & 0xFF, blue1:int = (_color1 & 0xFF) - blue0 ; for (i = 0; i != q+1;++i) { palette[i]= (( i / q * red1 + red0 )& 0xFF0000 ) | (( i / q * green1 + green0 )& 0xFF00 ) | (( i / q * blue1 + blue0 )& 0xFF ) | 0xFF000000 ; } } public function getValueAt(x:int, y:int):uint { return getPixel(x,y)&0xFF; } public function getCellAt(x:int, y:int):uint { return (x>-1 && y>-1 && x