By Zevan | March 17, 2009
Actionscript:
-
var canvas:BitmapData = new BitmapData(400,400, false, 0xFFFFFF);
-
addChild(new Bitmap(canvas));
-
var eraser:BitmapData = new BitmapData(400,400, true, 0x33FFFFFF);
-
-
var particles:Array = new Array();
-
for (var i:int = 0; i <1000; i++){
-
particles.push(makeParticle());
-
}
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
canvas.copyPixels(eraser, eraser.rect, new Point(0,0), null, null, true);
-
for (var i:int = 0; i <particles.length; i++){
-
particles[i]();
-
}
-
}
-
-
function makeParticle():Function {
-
var dx:Number, dy:Number;
-
var x:Number = 200;
-
var y:Number = 200;
-
var vx:Number = Math.random() * 4 - 2;
-
var vy:Number = Math.random() * 4 - 2;
-
return function():void {
-
x += vx;
-
y += vy;
-
dx = x - 200;
-
dy= y - 200;
-
if (Math.sqrt((dx * dx) + (dy * dy))> 100){
-
vx *= -1;
-
vy *= -1;
-
}
-
canvas.setPixel(x, y, 0x000000);
-
}
-
}
This creates a circular area filled with moving particles/pixels. It makes use of yesterdays functional programming techniques.
By Zevan | March 12, 2009
Actionscript:
-
var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(400, 400, false, 0x000000)))).bitmapData;
-
-
function line(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):void{
-
var dx:Number = x2 - x1;
-
var dy:Number = y2 - y1;
-
var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
-
var step:Number = 1 / (dist / res);
-
for (var i:Number = 0; i<=1; i+= step){
-
// lerp : a + (b - a) * f
-
canvas.setPixel(x1 + dx * i, y1 + dy * i, 0xFFFFFF);
-
}
-
}
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
canvas.fillRect(canvas.rect, 0x000000);
-
line(100 , 100, mouseX, mouseY,1);
-
line(100 + 50, 100, mouseX+ 50, mouseY,5);
-
}
Yesterday I posted an implementation of the Bresenham Line Algorithm. Today I'm posting a comparatively slow way to draw a line with setPixel(). This snippet uses lerp and the Pythagorean theorem. It works nicely for small numbers of lines, its easy to draw dotted lines with it and its easy to explain. In a real app where you needed to use setPixel() to draw a line you should use one of the fast algorithms like Wu or Bresenham.
I didn't originally write this snippet to use set pixel... a few weeks ago I wrote something very similar to calculate a set of x y coords between two given points. In the program I used it in speed wasn't an issue (as I only needed to run the function one time). I've needed this kind of function many times before in games and small apps...
This was the original:
Actionscript:
-
function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):Array{
-
var points:Array = new Array();
-
var dx:Number = x2 - x1;
-
var dy:Number = y2 - y1;
-
var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
-
var step:Number = 1 / (dist / res);
-
for (var i:Number = 0; i<=1; i+= step){
-
points.push(new Point(x1 + dx * i, y1 + dy * i));
-
}
-
return points;
-
}
-
-
trace(calculatePoints(0,0,100,0,10));
-
/* outputs:
-
(x=0, y=0),(x=10, y=0),(x=20, y=0),(x=30.000000000000004, y=0),(x=40, y=0),(x=50, y=0),(x=60, y=0),(x=70, y=0),(x=80, y=0),(x=89.99999999999999, y=0),(x=99.99999999999999, y=0)
-
*/
...and another version to allow you to specify the number of points to calculate rather than the pixel interval at which they should be calculated:
Actionscript:
-
function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, pointNum:int=10):Array{
-
var points:Array = new Array();
-
var step:Number = 1 / (pointNum + 1);
-
for (var i:Number = 0; i<=1; i+= step){
-
points.push(new Point(x1 + (x2 - x1) * i, y1 + (y2 - y1) * i));
-
}
-
return points;
-
}
-
-
trace(calculatePoints(0,30,30,0,1));
-
/* outputs:
-
(x=0, y=30),(x=15, y=15),(x=30, y=0)
-
*/
This last version isn't perfect, sometimes the pointNum will be off by 1, I may fix that in a future post.
By Zevan | March 11, 2009
Actionscript:
-
var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(400,400, false, 0x000000)))).bitmapData;
-
-
drawLine(10,10,100,90, 0xFF0000);
-
drawLine(100,90,60,80, 0xFF0000);
-
drawLine(100,90,95,60, 0xFF0000);
-
-
for (var i:int = 0; i<100; i+=1){
-
drawLine(i *4, 100 + i, 200, 390);
-
}
-
// code ported from here:
-
// http://www.edepot.com/linebenchmark.html
-
function drawLine(x1:int, y1:int, x2:int, y2:int, col:uint = 0xFFFFFF){
-
var x:int, y:int;
-
var dx:int, dy:int;
-
var incx:int , incy:int
-
var balance:int;
-
-
if (x2>= x1){
-
dx = x2 - x1;
-
incx = 1;
-
}else{
-
dx = x1 - x2;
-
incx = -1;
-
}
-
-
if (y2>= y1){
-
dy = y2 - y1;
-
incy = 1;
-
}else{
-
dy = y1 - y2;
-
incy = -1;
-
}
-
-
x = x1;
-
y = y1;
-
-
if (dx>= dy){
-
dy <<= 1;
-
balance = dy - dx;
-
dx <<= 1;
-
-
while (x != x2){
-
canvas.setPixel(x, y, col);
-
if (balance>= 0){
-
y += incy;
-
balance -= dx;
-
}
-
balance += dy;
-
x += incx;
-
}
-
canvas.setPixel(x, y, col);
-
}else{
-
dx <<= 1;
-
balance = dx - dy;
-
dy <<= 1;
-
-
while (y != y2){
-
canvas.setPixel(x, y, col);
-
if (balance>= 0){
-
x += incx;
-
balance -= dy;
-
}
-
balance += dx;
-
y += incy;
-
}
-
canvas.setPixel(x, y, col);
-
}
-
}
This snippet shows Brensenham's line drawing algorithm. I ported this implementation from here... all the line algorithms in that link are easy to port to actionscript. I've messed with them all at some point.
Tomorrow I'm going to post a super slow line drawing algorithm... so I figured I'd post a fast line drawing algorithm today.
Actionscript:
-
[SWF(width = 600, height = 600)]
-
var a:Number = 0.02;
-
var b:Number = .9998;
-
-
var xn1:Number = 5;
-
var yn1:Number = 0;
-
var xn:Number, yn:Number;
-
-
var scale:Number = 10;
-
var iterations:Number = 20000;
-
-
function f(x:Number):Number{
-
var x2:Number = x * x;
-
return a * x + (2 * (1 - a) * x2) / (1 + x2);
-
}
-
-
var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(600,600,false,0xEFEFEF)))).bitmapData;
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
-
canvas.fillRect(canvas.rect, 0xEFEFEF);
-
a = mouseY / 1000;
-
xn1 = mouseX / 30;
-
yn1 = 0;
-
for (var i:int = 0; i<iterations; i++){
-
xn = xn1;
-
yn = yn1;
-
-
xn1 = b * yn + f(xn);
-
yn1 = -xn + f(xn1);
-
canvas.setPixel( 280 + xn1 * scale, 300 + yn1 * scale, 0x000000);
-
}
-
}
Notice the setup for this is very similar to yesterdays flames attractor post.
Back in october of last year I stumbled upon the excellent subblue website by Tom Beddard. I was REALLY impressed by a blog post about Gumowski / Mira patterns. If you haven't seen it you should go take a look.
I'd never heard of Gumowski / Mira patterns before and made a mental note to go and try to read about them and maybe find an equation to port to actionscript or processing. Anyway, a few days ago I decided to go ahead and look up the math and... this is the result.
I got equation over at mathworld...
For simplicity I intentionally made the actionscript code look as much like the mathworld equation as possible. Using f for my function name and using xn1, yn1 etc... There are a few speed optimizations that could be made but I wanted this snippet to be very readable.
Here are a few examples of what this code will generate:

Also posted in Math | Tagged actionscript, flash |