3/29/2011

Generative Art and Bitmaps

Generative art refers to art created via algorithms and Flash is a perfect tool for it. This post will look into the basics of generative art using as3's powerful Bitmap class.

The gist of generative art involves a repeating algorithm, and it usually contains a degree of randomness. In this tutorial, we will create a rotating triangle that increases in length as it rotates (imagine a clock's hour hand increasing in length into a minute hand as it rotates around the clock). It will also appear in random locations once it's done with one rotation. Every update will be recorded and drawn, producing an interesting image of overlapping "rays". This is what it'll look like in one rotation:

We will be using a Bitmap to record the rotating graphic. A good analogy is to see the Bitmap as a painter's canvas and the rotating quadrilateral graphic as the brush the painter uses. Creating our canvas Bitmap to start off:
import flash.display.BitmapData; import flash.display.Bitmap; var sWid:Number=stage.stageWidth; var sHei:Number=stage.stageHeight; var bmd:BitmapData=new BitmapData(sWid,sHei,false,0xFFFFFF); var canvas=new Bitmap(bmd); stage.addChild(canvas); The BitmapData class lets you work with the data (pixels) of a Bitmap object. Take a look here to learn about its constructor parameters. Then a Bitmap (canvas) is created using that BitmapData and added to stage.

Next, we add our brush: import flash.display.Sprite; var brush:Sprite=new Sprite(); stage.addChild(sq); Nothing special here. It is an empty Sprite because we will do the drawing of it in an ENTER_FRAME function.


Now let's get on to where the action is.  This ENTER_FRAME function is where we update the brush, move it, and draw it on to the canvas. We'll also need some variables control the looks and movement of our brush. var at:int=0; // current iteration var color:int=0; // color of brush var alph:Number=0.1; // alpha of brush var brushwid:Number=20; // triangle width of brush var rotChange:int=4; // degree change per iteration var times:int=int(360/rotChange); // times to iterate stage.addEventListener(Event.ENTER_FRAME,drawFunc); function drawFunc(e:Event){ if(at<times){ brush.graphics.clear(); brush.graphics.beginFill(color,alph); brush.graphics.lineTo(0,at*10); brush.graphics.lineTo(brushwid,at*10); brush.graphics.lineTo(0,0); brush.rotation+=dir; at++; }else{ reset(); } bmd.draw(this); } As you can see in the drawFunc function, we draw our triangle brush and increasing its length by 10 px every iteration. We also change its rotation. Then we draw the brush onto the BitmapData. The canvas Bitmap updates automatically. We have to pass "this" to the draw function and not the brush object itself because we also want the position and rotation of the brush. Once it iterated enough times, it resets. 


The reset function is where the brush resets itself and moves to a random location on the screen: function reset(){ at=0; rotChange=int(Math.random()*2)*-8+4; // -4 or 4 brushwid=10+int(Math.random()*9); // random 10-20 color=Math.random()*0xFFFFFF; // random color brush.graphics.clear(); brush.rotation=Math.random()*360; // random pos in the middle 3/5 of screen brush.x=sWid/5+(Math.random()*sWid*3/5); brush.y=sHei/5+(Math.random()*sHei*3/5); } It's just some math that resets the brush to a random rotation, color, width, and location. And with that, we are done!


Check out the masterpiece (click on it to restart):


And that is all you need to create basic generative art. Here is the full code you can copy/paste and play with. You can mess with the variables, the way the brush looks, the behavior of the brush, the location of each iteration, etc. The possibilities are endless! import flash.display.BitmapData; import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; var sWid:Number=stage.stageWidth; var sHei:Number=stage.stageHeight; var bmd:BitmapData=new BitmapData(sWid,sHei,false,0xFFFFFF); var canvas=new Bitmap(bmd); var brush=new Sprite(); var at:int=0; var color:int=0; var alph:Number=0.1; var brushwid:Number=20; var rotChange:int=4; var times:Number=Math.ceil(360/rotChange); addChild(canvas); addChild(brush); reset(); stage.addEventListener(Event.ENTER_FRAME,drawFunc); function drawFunc(e:Event):void{ if(at<times){ brush.graphics.clear(); brush.graphics.beginFill(color,alph); brush.graphics.lineTo(0,at*10); brush.graphics.lineTo(brushwid,at*10); brush.graphics.lineTo(0,0); brush.rotation+=rotChange; at++; }else{ reset(); } bmd.draw(stage); } function reset():void{ at=0; rotChange=int(Math.random()*2)*-8+4; brushwid=10+int(Math.random()*9); color=Math.random()*0xFFFFFF; brush.graphics.clear(); brush.rotation=Math.random()*360; brush.x=sWid/5+(Math.random()*sWid*3/5); brush.y=sHei/5+(Math.random()*sHei*3/5); } Here is another with the same concept.

2 comments:

  1. im looking for random colored autumn leaves. this tutorial will help me.

    ReplyDelete