Rotating Particles with PerlinNoise

Continuing on with my previous post on scaling particles with PerlinNoise, I decided to take it a little further by playing with each particle's rotation in relation to the white and dark values in the PerlinNoise. This is another little trick I learned from Robert Hodgin's presentation at FlashBelt on how to simulate realistic motion on how objects reacted to wind.

When wind blows, it doesn't just blow all objects at the same speed, direction, and force, all in a straight line. There are many parameters that can alter the way one object moves from within a large group of objects.

While PerlinNoise does not simulate wind patterns, the sheer randomness it provides allows us the ability to fake an effect such as the way a field of grass blows in the breeze, or the way a group of leaves on a tree blow in the wind.

The below example takes an object from the library, duplicates it a set amount of times, and applies it to the stage at a random position. The basic logic of the rotation is; to scan the entire PerlinNoise bitmap and gather the minimum and maximum color numbers from all the pixels within that bitmap, the take the current pixel color directly beneath the particle and subtract it by the minimum color value. Then take that value divided by  the maximum color value, and then multiply that value by 360.

(Note: If the below example is not displaying the particles, it's probably because you are using FireFox 3.0 on a Mac with Add-ons. This is something I just noticed, and seems to be a bug with FF3 being a little more picky in how you call your code. Working on the the fix — when I get some time. Until then, I'm afraid you'll have to disable you add-ons if you want to view).

import flash.display.StageAlign;
import flash.display.StageScaleMode;
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 = stage.stageWidth;
var perlinH:int = 250;
var baseX:int = 275;
var baseY:int = 275;
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 = 15;
var ySpeed:int = 15;
var tnodes:int = 2500;
 
/* ------------------------------------------------------------------------------------------------
// 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);
var myImage:Bitmap = new Bitmap(myBD);
addChild(myImage);
 
/* ------------------------------------------------------------------------------------------------
// create nodes
--------------------------------------------------------------------------------------------- */
 
for (var i:int = 0; i < tnodes; i++) {
 
var myNode:Ball = new Ball();
addChild(myNode);
 
myNode.x = int(Math.random() * perlinW);
myNode.y = int(Math.random() * perlinH);
 
myNode.addEventListener(Event.ENTER_FRAME, scaleNode);
}
 
/* ------------------------------------------------------------------------------------------------
// run perlinNoise
--------------------------------------------------------------------------------------------- */
 
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event) {
 
offset[0].x += xSpeed;
offset[0].y += 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));
}
}
}
 
/* ------------------------------------------------------------------------------------------------
// update Node
--------------------------------------------------------------------------------------------- */
 
function scaleNode(e:Event):void {
 
// find pixel color under node
var curColor:int = myBD.getPixel(e.currentTarget.x, e.currentTarget.y);
 
// find rotation by taking the difference of current color - minColor and the maxColor
var Rotation:Number = (curColor - minColor) / maxColor;
 
// update properties
e.currentTarget.rotation = Rotation * 360;
e.currentTarget.scaleX = curColor * .0000001;
e.currentTarget.scaleY = curColor * .0000001;
}
 
// hide noise and get min/max color values
myImage.visible = false;
updateMinMaxPixel();

Scaling Particles with PerlinNoise

While attending FlashBelt this past June, I was left in complete awe by the presentation Robert Hodgin put together, and his ability to create life-like motion using PerlinNoise.

While Robert uses Processing over Flash, the logic is much the same. Use PerlinNoise, BitmapData, and getPixel to manipulate the way your objects move.

This is my first attempt at exploring this idea. Below is a very simple example of scaling particles using PerlinNoise. The basic idea of this experiment is that the lighter the pixel value in the PerlinNoise is, the larger the particles will scale. Then the darker the pixel data in the Noise is, the smaller the particles will scale. Use the controls to play with the parameters of the noise.

(Read More...)

AS3 QueryString Class V1

05.09.08 // Query Strings // Comments (8) //

Today I was working on a video player in AS3 that I wanted to be able to play any video on initial load by passing a variable through the query string. I had done this before in AS2 using the ExternalInterface class but wasn't sure if it was still valid in AS3. After a little quick research, I found that this is one thing that they left alone between the two versions.

So after a few minor AS2 to AS3 migrating, I now have an AS3 version of my QueryString class. The following app allows you to search through a query string for a value of a specified variable. To test, add a query string to the url and play.

(Read More...)

Going Nude for the Day

04.09.08 // CSS // Comments (0) //

In honor of the third annual CSS Naked Day, I have commented out my stylesheets for the day.

AS3 Perlin Noise Ripples

Using the same logic from my wave machine, I reworked the code to make an AS3 version. What I learned is that there isn't really any difference with the perlinNoise method from AS2 to AS3. (Read More...)

PaperVision 2.0 Rotating Cube v1

Inspired by Lee Brimelow's tutorial on PaperVision 2.0 interactivity, I finally got my hands dirty playing with the 2.0 GreatWhite branch today. (Read More...)

AS3 Drawing App — v1

This is a simple little drawing app class I call draw.Pencil. It allows full custom ability to define the stroke width, alpha, color, cap, scaleMode, and the ability to clear on each mouse press. Right now it only allows said parameters to be defined when the instance is created. The next version will allow for change in parameters to be made on the fly. (Read More...)

A.S. 3.0 Draw Circle Class — V2

With version 2 of my draw.Circle class, I've included gradient control as well as more control on the stroke by adding parameters for pixelHinting, and scaleMode. (Read More...)

A.S. 3.0 Draw Circle Class — V1

I've finally been getting around to re-writing all my ActionScript 2.0 classes in ActionScript 3.0. Since a lot of A.S. 3 is still a little foreign to me, I thought I'd start simple with re-creating my shape classes. First up, draw.Circle. (Read More...)

E-Z-GO RXV Microsite

02.13.08 // Work // Comments (0) //

E-Z-GO RXV Microsite


Recently just launched the E-Z-GO Microsite at work. This project gave us the opportunity to incorporate some great 3D work made by the talented people at MAKE Visual.