Slow Line Drawing

Actionscript:
  1. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(400, 400, false, 0x000000)))).bitmapData;
  2.  
  3. function line(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):void{
  4.     var dx:Number = x2 - x1;
  5.     var dy:Number = y2 - y1;
  6.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  7.     var step:Number = 1 / (dist / res);
  8.     for (var i:Number = 0; i<=1; i+= step){
  9.         // lerp : a  + (b - a) * f
  10.         canvas.setPixel(x1 + dx * i, y1 + dy * i, 0xFFFFFF);
  11.     }
  12. }
  13.  
  14. addEventListener(Event.ENTER_FRAME, onLoop);
  15. function onLoop(evt:Event):void {
  16.    canvas.fillRect(canvas.rect, 0x000000);
  17.   line(100 , 100, mouseX, mouseY,1);
  18.   line(100 + 50, 100, mouseX+ 50, mouseY,5);
  19. }

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:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):Array{
  2.     var points:Array = new Array();
  3.     var dx:Number = x2 - x1;
  4.     var dy:Number = y2 - y1;
  5.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  6.     var step:Number = 1 / (dist / res);
  7.     for (var i:Number = 0; i<=1; i+= step){
  8.         points.push(new Point(x1 + dx * i, y1 + dy * i));
  9.     }
  10.     return points;
  11. }
  12.  
  13. trace(calculatePoints(0,0,100,0,10));
  14. /* outputs:
  15. (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)
  16. */

...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:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, pointNum:int=10):Array{
  2.     var points:Array = new Array();
  3.     var step:Number = 1 / (pointNum + 1);
  4.     for (var i:Number = 0; i<=1; i+= step){
  5.         points.push(new Point(x1 + (x2 - x1) * i, y1 + (y2 - y1) * i));
  6.     }
  7.     return points;
  8. }
  9.  
  10. trace(calculatePoints(0,30,30,0,1));
  11. /* outputs:
  12. (x=0, y=30),(x=15, y=15),(x=30, y=0)
  13. */

This last version isn't perfect, sometimes the pointNum will be off by 1, I may fix that in a future post.

This entry was posted in Math, graphics algorithms, misc, pixel manipulation, setPixel and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*