By Zevan | January 9, 2009
Actionscript:
-
var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
-
addChild(new Bitmap(canvas));
-
-
drawCircle(200,100, 50);
-
-
// y, y radius, color
-
function drawCircle(xp:Number,yp:Number, radius:Number, col:uint =0x000000):void {
-
var balance:int;
-
var xoff:int;
-
var yoff:int;
-
xoff=0;
-
yoff=radius;
-
balance=- radius;
-
-
while (xoff <= yoff) {
-
canvas.setPixel(xp+xoff, yp+yoff, col);
-
canvas.setPixel(xp-xoff, yp+yoff, col);
-
canvas.setPixel(xp-xoff, yp-yoff, col);
-
canvas.setPixel(xp+xoff, yp-yoff, col);
-
canvas.setPixel(xp+yoff, yp+xoff, col);
-
canvas.setPixel(xp-yoff, yp+xoff, col);
-
canvas.setPixel(xp-yoff, yp-xoff, col);
-
canvas.setPixel(xp+yoff, yp-xoff, col);
-
-
if ((balance += xoff++ + xoff)>= 0) {
-
balance-=--yoff+yoff;
-
}
-
}
-
}
The above demos a circle drawing algorithm. This will draw an outlined circle with no fill. This implementation doesn't use multiplication.
Using setPixel to draw primitive shapes can be a good learning experience. I found this basic implementation of the Bresenham Circle algorithm a few years back and lost the original link.... I dug around for a good hour trying to find the original but to no avail. So if someone recognizes this interesting implementation .... let me know
The original code was written in java I think.
If your curious. The standard implementation I keep finding online looks something like this:
Actionscript:
-
// ported from http://www.codeuu.com/Bresenham_Circle
-
function drawCircle(cx:Number, cy:Number, r:Number, col:uint):void{
-
var xp:int = 0, yp:int= r ;
-
var d:int = 3 - (2 * r);
-
-
while(xp <= yp){
-
-
canvas.setPixel(cx+xp,cy+yp,col);
-
canvas.setPixel(cx+yp,cy+xp,col);
-
canvas.setPixel(cx-xp,cy+yp,col);
-
canvas.setPixel(cx+yp,cy-xp,col);
-
canvas.setPixel(cx-xp,cy-yp,col);
-
canvas.setPixel(cx-yp,cy-xp,col);
-
canvas.setPixel(cx+xp,cy-yp,col);
-
canvas.setPixel(cx-yp,cy+xp,col);
-
-
if (d<0){
-
d += (4*xp)+6;
-
}else{
-
d += (4*(xp-yp))+10;
-
yp -= 1;
-
}
-
xp++;
-
}
-
-
}
I did a few speed tests against the first one that doesn't make use of multiplication and it is only ever so slightly faster....
By Zevan | December 28, 2008
Actionscript:
-
// isometric conversion
-
var centerX:Number=stage.stageWidth/2;
-
var centerY:Number=stage.stageHeight/2;
-
var theta:Number=Math.PI/4;// 45 degrees;
-
var cosX:Number=Math.cos(theta);
-
var sinX:Number=Math.sin(theta);
-
var pnt:Point = new Point();
-
function iso3D(x:Number, y:Number, z:Number):Point {
-
pnt.x = centerX + (x-z) * cosX
-
pnt.y = centerY - (x+z) * 0.5 * sinX - y;
-
return pnt;
-
}
-
// example:
-
var canvas:BitmapData=new BitmapData(stage.stageWidth,stage.stageHeight,true,0xFF000000);
-
addChild(new Bitmap(canvas,"auto",true));
-
var size:int=100;
-
var hs:int=size / 2;
-
var pen:Point = new Point();
-
var vect:Vector3D = new Vector3D();
-
// draw a few shapes with offset:
-
for (var dist:int = 10; dist <= 80; dist *= 2) {
-
// voxel space:
-
for (var i:int = 0; i<size; i++) {
-
for (var j:int = 0; j<size; j++) {
-
for (var k:int = 0; k<size; k++) {
-
vect.x=j-hs;
-
vect.y=i-hs;
-
vect.z=k-hs;
-
pen = iso3D(vect.x,vect.y,vect.z);
-
if (Math.sqrt((vect.x * vect.x) + (vect.y * vect.y) + (vect.z * vect.z)) <dist) {
-
// using Vector3D.distance() is very slow compared to above
-
// a few types of coloring:
-
var xp:Number = pen.x + (dist <<2) - 200;
-
canvas.setPixel(xp, pen.y-100, (i <<16 | j <<8 | k) <<1);
-
canvas.setPixel(xp, pen.y+100, (k <<16 | k <<8 | k+j) );
-
}
-
}
-
}
-
}
-
}
The above will draw this:

You can read more about voxels here.
This isn't the speediest way to do voxels (especially if you want to animate). This was just the first thing that came to mind.
By Zevan | December 14, 2008
Actionscript:
-
var canvas:BitmapData=new BitmapData(255,255,false,0x000000);
-
addChild(new Bitmap(canvas, "auto", true));
-
-
var size:int = canvas.width * canvas.height;
-
-
var pixels:Vector.<uint> = new Vector.<uint>(size);
-
-
for (var i:int = 0; i<size; i++) {
-
var ox:uint= i % canvas.width;
-
var oy:uint= i / canvas.width;
-
pixels[i] = oy <<16 | ox;
-
}
-
-
canvas.setVector(canvas.rect, pixels);
setVector() is used to set a group of pixels. I've been wanting this feature for a long time. I'm assuming that it's at least a little faster than using a bunch of setPixel() calls, but i haven't tested it. Of course, Pixel Bender will be much faster than this.... as long as your not on a powerPC based mac (or some other older computer) ... as you may or may not know Pixel Bender will run very slow on a powerPC mac:
Quote from Tinic Uro - Flash Player Engineer
But... I have more news you might not like.
If you ever run a Pixel Bender filter on PowerPC based Mac you will see that it runs about 10 times slower than on an Intel based Mac. For this release we only had time to implement a JIT code engine for Intel based CPUs. On a PowerPC Mac Pixel Bender kernels will run in interpreted mode. I leave it up to you to make a judgment of how this will affect you. All I can say: Be careful when deploying content using Pixel Bender filters, know your viewers.
Read the rest of the article here.
By Zevan | December 13, 2008
Actionscript:
-
var canvas:BitmapData=new BitmapData(255,255,false,0x000000);
-
addChild(new Bitmap(canvas, "auto", true));
-
-
scaleX = scaleY = 1.5;
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
for (var i:int = 0; i<canvas.width * canvas.height; i++) {
-
var ox:int= i % canvas.width;
-
var oy:int= i / canvas.width;
-
var col = (ox | oy) * mouseX % 255;
-
canvas.setPixel(ox, oy, col <<16 | col <<8 | col);
-
}
-
}
Sometimes when I'm writing a program that does some pixel pushing I'll save the file and then start arbitrarily adding bitwise operations to it.... just to see what happens. Sierpinski-esque stuff occurs often. This will work in your timeline - move your mouse left and right to generate images like these:




