Category Archives: pixel manipulation

Bresenham Circle Filled

Actionscript:
  1. var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
  2. addChild(new Bitmap(canvas));
  3.  
  4. fillCircle(100,100,50,0xFF0000);
  5.  
  6. function fillCircle(xp:Number,yp:Number, radius:Number, col:uint = 0x000000):void {
  7.     var xoff:int =0;
  8.     var yoff:int = radius;
  9.     var balance:int = -radius;
  10.  
  11.     while (xoff <= yoff) {
  12.          var p0:int = xp - xoff;
  13.          var p1:int = xp - yoff;
  14.          
  15.          var w0:int = xoff + xoff;
  16.          var w1:int = yoff + yoff;
  17.          
  18.          hLine(p0, yp + yoff, w0, col);
  19.          hLine(p0, yp - yoff, w0, col);
  20.          
  21.          hLine(p1, yp + xoff, w1, col);
  22.          hLine(p1, yp - xoff, w1, col);
  23.        
  24.         if ((balance += xoff++ + xoff)>= 0) {
  25.             balance-=--yoff+yoff;
  26.         }
  27.     }
  28. }
  29.  
  30. function hLine(xp:Number, yp:Number, w:Number, col:uint):void {
  31.     for (var i:int = 0; i <w; i++){
  32.         canvas.setPixel(xp + i, yp, col);
  33.     }
  34. }

An implementation of yesterdays post that draws a filled circle instead of an outlined circle.

Also posted in BitmapData, graphics algorithms, setPixel | Tagged , | Leave a comment

Bresenham Circle No Multiplication

Actionscript:
  1. var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
  2. addChild(new Bitmap(canvas));
  3.  
  4. drawCircle(200,100, 50);
  5.  
  6. // y, y radius, color
  7. function drawCircle(xp:Number,yp:Number, radius:Number, col:uint =0x000000):void {
  8.     var balance:int;
  9.     var xoff:int;
  10.     var yoff:int;
  11.     xoff=0;
  12.     yoff=radius;
  13.     balance=- radius;
  14.  
  15.     while (xoff <= yoff) {
  16.         canvas.setPixel(xp+xoff, yp+yoff, col);
  17.         canvas.setPixel(xp-xoff, yp+yoff, col);
  18.         canvas.setPixel(xp-xoff, yp-yoff, col);
  19.         canvas.setPixel(xp+xoff, yp-yoff, col);
  20.         canvas.setPixel(xp+yoff, yp+xoff, col);
  21.         canvas.setPixel(xp-yoff, yp+xoff, col);
  22.         canvas.setPixel(xp-yoff, yp-xoff, col);
  23.         canvas.setPixel(xp+yoff, yp-xoff, col);
  24.  
  25.         if ((balance += xoff++ + xoff)>= 0) {
  26.             balance-=--yoff+yoff;
  27.         }
  28.     }
  29. }

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:
  1. // ported from http://www.codeuu.com/Bresenham_Circle
  2. function drawCircle(cx:Number, cy:Number, r:Number, col:uint):void{
  3.     var xp:int  = 0, yp:int= r ;
  4.     var d:int = 3 - (2 * r);
  5.    
  6.     while(xp <= yp){
  7.        
  8.         canvas.setPixel(cx+xp,cy+yp,col);
  9.         canvas.setPixel(cx+yp,cy+xp,col);
  10.         canvas.setPixel(cx-xp,cy+yp,col);
  11.         canvas.setPixel(cx+yp,cy-xp,col);
  12.         canvas.setPixel(cx-xp,cy-yp,col);
  13.         canvas.setPixel(cx-yp,cy-xp,col);
  14.         canvas.setPixel(cx+xp,cy-yp,col);
  15.         canvas.setPixel(cx-yp,cy+xp,col);
  16.        
  17.         if (d<0){
  18.             d += (4*xp)+6;
  19.         }else{
  20.             d += (4*(xp-yp))+10;
  21.             yp -= 1;
  22.         }
  23.         xp++;
  24.     }
  25.    
  26. }

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....

Also posted in BitmapData, graphics algorithms, setPixel | Tagged , , , | Leave a comment

BitmapData.floodFill()

Actionscript:
  1. var canvas:BitmapData = new BitmapData(400,400,false, 0xCC0000);
  2. addChild(new Bitmap(canvas));
  3.  
  4. var s:Shape = new Shape();
  5. s.graphics.beginFill(0x00CCCC);
  6. s.graphics.moveTo(Math.random()*400,Math.random()*400);
  7. for(var i:int = 0; i<10; i++){
  8.     s.graphics.lineTo(Math.random()*400,Math.random()*400);
  9. }
  10. canvas.draw(s);
  11.  
  12. stage.addEventListener(MouseEvent.CLICK, onDown);
  13. function onDown(evt:MouseEvent):void {
  14.     canvas.floodFill(mouseX, mouseY, 0x000000);
  15. }

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 , | Leave a comment

Isometric Voxels

Actionscript:
  1. // isometric conversion
  2. var centerX:Number=stage.stageWidth/2;
  3. var centerY:Number=stage.stageHeight/2;
  4. var theta:Number=Math.PI/4;// 45 degrees;
  5. var cosX:Number=Math.cos(theta);
  6. var sinX:Number=Math.sin(theta);
  7. var pnt:Point = new Point();
  8. function iso3D(x:Number, y:Number, z:Number):Point {
  9.     pnt.x = centerX + (x-z) *  cosX
  10.     pnt.y = centerY -  (x+z) * 0.5 * sinX - y;
  11.     return pnt;
  12. }
  13. // example:
  14. var canvas:BitmapData=new BitmapData(stage.stageWidth,stage.stageHeight,true,0xFF000000);
  15. addChild(new Bitmap(canvas,"auto",true));
  16. var size:int=100;
  17. var hs:int=size / 2;
  18. var pen:Point = new Point();
  19. var vect:Vector3D = new Vector3D();
  20. // draw a few shapes with offset:
  21. for (var dist:int = 10; dist <= 80; dist *= 2) {
  22.     // voxel space:
  23.     for (var i:int = 0; i<size; i++) {
  24.         for (var j:int = 0; j<size; j++) {
  25.             for (var k:int = 0; k<size; k++) {
  26.                 vect.x=j-hs;
  27.                 vect.y=i-hs;
  28.                 vect.z=k-hs;
  29.                 pen = iso3D(vect.x,vect.y,vect.z);
  30.                 if (Math.sqrt((vect.x * vect.x) + (vect.y * vect.y) + (vect.z * vect.z)) <dist) {
  31.                     // using Vector3D.distance() is very slow compared to above
  32.                     // a few types of coloring:
  33.                     var xp:Number = pen.x + (dist <<2) - 200;
  34.                     canvas.setPixel(xp, pen.y-100, (i <<16 | j <<8 | k) <<1);
  35.                     canvas.setPixel(xp, pen.y+100, (k <<16 | k <<8 | k+j)  );
  36.                 }
  37.             }
  38.         }
  39.     }
  40. }

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.

Also posted in 3D, BitmapData, color, setPixel | Tagged , , , | 3 Comments