By Zevan | January 11, 2009
Actionscript:
-
var canvas:BitmapData=new BitmapData(280,280,false,0x000000);
-
addChild(new Bitmap(canvas, PixelSnapping.AUTO, true));
-
var color:uint;
-
// anchor x1, anchor y1,
-
// control-handle x2, control-handle y2,
-
// anchor x3, anchor y3, [resolution incremental value between 0-1]
-
function quadBezier(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, resolution:Number=.03):void {
-
var b:Number,pre1:Number,pre2:Number,pre3:Number,pre4:Number;
-
for (var a:Number = 0; a <1;a+=resolution) {
-
-
b=1-a;
-
pre1=(a*a);
-
pre2=2*a*b;
-
pre3=(b*b);
-
-
canvas.setPixel(pre1*x1 + pre2*x2 + pre3*x3 ,
-
pre1*y1 + pre2*y2 + pre3*y3, color);
-
}
-
}
-
-
// draw a few
-
color = 0xFFFFFF;
-
-
for (var i:int = 0; i<20; i++){
-
quadBezier(40,100, 150 , 20 + i * 10 , 200, 100,.01);
-
}
-
-
color = 0xFF0000;
-
-
for (i= 0; i<20; i++){
-
quadBezier(150,200, 100 + i * 10, 100 , 120, 30,.01);
-
}
The above demos a function that draws quadratic bezier curves using setPixel().
One of the first posts on this site was a snippet that used setPixel() to draw a cubic bezier curve. I recently needed to do the exact same thing but I wanted to use a quadratic bezier... I knew I had the code laying around somewhere, but I couldn't seem to find it so I just looked on wikipedia and changed the previous cubicBezier() function accordingly.
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.