By Zevan | January 10, 2009
Actionscript:
-
var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
-
addChild(new Bitmap(canvas));
-
-
fillCircle(100,100,50,0xFF0000);
-
-
function fillCircle(xp:Number,yp:Number, radius:Number, col:uint = 0x000000):void {
-
var xoff:int =0;
-
var yoff:int = radius;
-
var balance:int = -radius;
-
-
while (xoff <= yoff) {
-
var p0:int = xp - xoff;
-
var p1:int = xp - yoff;
-
-
var w0:int = xoff + xoff;
-
var w1:int = yoff + yoff;
-
-
hLine(p0, yp + yoff, w0, col);
-
hLine(p0, yp - yoff, w0, col);
-
-
hLine(p1, yp + xoff, w1, col);
-
hLine(p1, yp - xoff, w1, col);
-
-
if ((balance += xoff++ + xoff)>= 0) {
-
balance-=--yoff+yoff;
-
}
-
}
-
}
-
-
function hLine(xp:Number, yp:Number, w:Number, col:uint):void {
-
for (var i:int = 0; i <w; i++){
-
canvas.setPixel(xp + i, yp, col);
-
}
-
}
An implementation of yesterdays post that draws a filled circle instead of an outlined circle.
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 31, 2008
Actionscript:
-
var canvas:BitmapData = new BitmapData(400,400,false, 0xCC0000);
-
addChild(new Bitmap(canvas));
-
-
var s:Shape = new Shape();
-
s.graphics.beginFill(0x00CCCC);
-
s.graphics.moveTo(Math.random()*400,Math.random()*400);
-
for(var i:int = 0; i<10; i++){
-
s.graphics.lineTo(Math.random()*400,Math.random()*400);
-
}
-
canvas.draw(s);
-
-
stage.addEventListener(MouseEvent.CLICK, onDown);
-
function onDown(evt:MouseEvent):void {
-
canvas.floodFill(mouseX, mouseY, 0x000000);
-
}
floodFill() is basically the paint bucket (fill) tool in any bitmap drawing program. The above example draws an arbitrary blue polygon to a red background. Click anywhere on the resulting image to see floodFill() in action.
floodFill() takes 3 arguments... x, y and color.
Also posted in BitmapData | Tagged actionscript, flash |
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.