Moving Particles with Perlin Noise
In my previous experiments using Perlin Noise to create random movement, I played around with adjusting the rotation and the scale of each particle by taking the current pixel color number beneath each node and gathering a percentage of that by the maximum color number in the Perlin Noise.
Here I use the same numbers to create a flocking-like movement to animate the x and y coordinates. This is another experiment I've been wanting to try since watching Robert Hodgin's examples on Perlin Noise flocking at FlashBelt earlier this summer. If you haven't seen his Birds yet, or any of his stuff for that matter, you should really check it out.
What I'm doing here is taking the same percentage mentioned above of the current node color number by the maximum color number in the Perlin Noise, multiplying that by 2 PI (to get the full 360°), and then taking the cosine of that for the x movement, and the sine of that value for the y movement, and then taking each of those values multiplied by a set random speed.
Looks like:
x += (xspeed * Math.cos(pixelColorPercentage * (Math.PI * 2)));
y += (yspeed * Math.sin(pixelColorPercentage * (Math.PI * 2)));
Play with the different Perlin Noise parameters to see how it effects the particles.
Note: The CPU performance improves a great deal when the PerlinNoise object is NOT added to the display list. For the sake of this example, I added to the display list to show how it effects the movement.
import flash.display.BitmapData; import flash.display.Graphics; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; /* ------------------------------------------------------------------------------------------------ // set up Perlin Noise Properties --------------------------------------------------------------------------------------------- */ var perlinW:int = 600; var perlinH:int = 250; var baseX:int = 400; var baseY:int = 50; var octaves:int = 1; var seed:int = Math.floor(Math.random()*100); var stitch:Boolean = true; var fractal:Boolean = true; var grayScale:Boolean = true; var channels:int = 1; var xSpeed:int = 10; var ySpeed:int = 3; var tnodes:int = 100; var speed:int = 2; /* ------------------------------------------------------------------------------------------------ // set up min/max color vars --------------------------------------------------------------------------------------------- */ var minColor:int = Number.MAX_VALUE; var maxColor:int = 0; var pixelData:int; /* ------------------------------------------------------------------------------------------------ // create offset --------------------------------------------------------------------------------------------- */ var point1:Point = new Point(0, 0); var point2:Point = new Point(0, 0); var offset:Array = [point1, point2]; /* ------------------------------------------------------------------------------------------------ // create bitmapData object --------------------------------------------------------------------------------------------- */ var myBD:BitmapData = new BitmapData(perlinW, perlinH); /* ------------------------------------------------------------------------------------------------ // run perlinNoise --------------------------------------------------------------------------------------------- */ offset[0].x += int(xSpeed); offset[0].y += int(ySpeed); myBD.perlinNoise(baseX, baseY, octaves, seed, stitch, fractal, channels, grayScale, offset); /* ------------------------------------------------------------------------------------------------ // get min/max pixel info --------------------------------------------------------------------------------------------- */ function updateMinMaxPixel():void { for (var i : int = 0;i < perlinW; i++) { for (var j : int = 0;j < perlinH; j++) { pixelData = int(myBD.getPixel(i, j)); minColor = int(Math.min(pixelData, minColor)); maxColor = int(Math.max(pixelData, maxColor)); } } } updateMinMaxPixel(); /* ------------------------------------------------------------------------------------------------ // create nodes --------------------------------------------------------------------------------------------- */ function addNodes():void { var i:int = tnodes; while (i > 0) { // build node var myNode:Ball = new Ball(); // position node myNode.x = perlinW/2; myNode.y = perlinH/2; myNode.xspeed = (Math.random() * speed) + speed; myNode.yspeed = (Math.random() * speed) + speed; // try drawing into a bitmap data myNode.addEventListener(Event.ENTER_FRAME, scaleNode); addChild(myNode); i --; } } /* ------------------------------------------------------------------------------------------------ // update Node --------------------------------------------------------------------------------------------- */ function scaleNode(e:Event):void { // find pixel color under node var curColor:int = myBD.getPixel(int(e.currentTarget.x), int(e.currentTarget.y)); // find rotation by taking the difference of current color - minColor and the maxColor var pixPerc:Number = Number((curColor - minColor) / maxColor); var oldX:Number = e.currentTarget.x; var oldY:Number = e.currentTarget.y; // update properties e.currentTarget.x += (e.currentTarget.xspeed * Math.cos(pixPerc * (Math.PI * 2))); e.currentTarget.y += (e.currentTarget.yspeed * Math.sin(pixPerc * (Math.PI * 2))); if (e.currentTarget.x < 0 || e.currentTarget.y < 0 || e.currentTarget.x > perlinW || e.currentTarget.y > perlinH) { e.currentTarget.xspeed = (Math.random() * speed) + speed; e.currentTarget.yspeed = (Math.random() * speed) + speed; e.currentTarget.x = perlinW/2; e.currentTarget.y = perlinH/2; } } addNodes();
[...] above example is another take on moving particles with perlinNoise. This time I’m containing the particles within a circular boundary by using the [...]
Pingback by Mike t. Henderson » Perlin Particles within a Circular Boundary — 3/6/09 @ 6:29 pm
[...] method. In previous posts I’ve experimented, using the number it returns, to scale, rotate, move, and in my last post, create a halftone [...]
Pingback by Mike t. Henderson » Pointillism in AS3 with BitmapData — 3/12/09 @ 12:19 am
[...] (required) Website © 2010 Aaron Benson. All rights reserved. Powered by WordPress …Mike t. Henderson | Web Designer. Actionscript enthusiast …I am an interactive designer, specializing in Actionscript on the Flash platform. … Name [...]
Pingback by pixeldata — 3/4/10 @ 6:47 pm