Tag Archives: as3

Tetris Sand CA

Actionscript:
  1. stage.frameRate = 30;
  2. scaleX = scaleY = 2.5;
  3. var canvas:BitmapData = new BitmapData(200,200,false, 0x000000);
  4. addChild(new Bitmap(canvas));
  5. var w:int = canvas.width;
  6. var size:int = canvas.width * canvas.height;
  7. var read:Vector.<uint> = new Vector.<uint>(size);
  8. var write:Vector.<uint> = new Vector.<uint>(size);
  9.  
  10. read = canvas.getVector(canvas.rect);
  11. var loc:int = 199*w;
  12. for(var i:int = 0; i <= 200; i++){
  13.        read[loc+i]=0xFFFFFFFF;
  14. }
  15. write = read.concat();
  16.  
  17. var shapes:Array = [];
  18. shapes[0] = [[1,1],[1,1]];
  19. shapes[1] = [[1,1,1,1]];
  20. shapes[2] = [[1],[1],[1],[1]];
  21. shapes[3] = [[1,1,1],[0,1,0]];
  22. shapes[4] = [[1,0],[1,1],[1,1],[0,1]];
  23. shapes[5] = [[1,0,0],[1,1,1]];
  24. shapes[6] = [[1,1,0], [0,1,1]];
  25. shapes[7] = [[1,1], [1,0],[1,0]];
  26. function drawShape(xp:int, yp:int, pattern:Array, col:uint):void{
  27.     var i:int = 0;
  28.     var loc:int = xp + yp * w;
  29.     if (int(Math.random()*2) == 1){
  30.         pattern.reverse();
  31.     }
  32.     if (int(Math.random()*2)){
  33.         for (i= 0; i<pattern.length; i++){
  34.             pattern[i].reverse();
  35.         }
  36.     }
  37.     for (i = 0; i<pattern.length; i++){
  38.          for (var j:int = 0; j<pattern[i].length; j++){
  39.              if (pattern[i][j] == 1){
  40.                 write[loc + i * w + j] = col;
  41.              }
  42.         }
  43.     }
  44. }
  45.  
  46. var counter:int = 0;
  47. addEventListener(Event.ENTER_FRAME, onLoop);
  48. function onLoop(evt:Event):void {
  49.      var i:int;
  50.      canvas.lock();
  51.      if (counter % 20 == 1){
  52.         for ( i= 0; i<20; i++){
  53.              drawShape(5+  i * 10, 10, shapes[int(Math.random() * shapes.length)], Math.random()*0xFFFFFF);
  54.         }
  55.      }
  56.      counter++;
  57.      read = write.concat();
  58.      for (i = 0; i<size; i++){
  59.          var curr:uint = read[i];
  60.          if (curr != 0xFF000000 && curr != 0xFFFFFFFF){
  61.             var below:uint = read[i + w];
  62.             if (below == 0xFF000000 || below == curr){
  63.               var above:uint = read[i - w];
  64.               if (above == 0xFF000000){
  65.                  write[i] = 0xFF000000;
  66.               }
  67.               write[i + w] = curr;
  68.             }else{
  69.                 var index:uint;
  70.                 if (int(Math.random()*2) == 1){
  71.                     index = i + w - 1;
  72.                 }else{
  73.                     index = i + w + 1;
  74.                 }
  75.                 if (read[index] == 0xFF000000){
  76.                     write[index] = curr;
  77.                 }
  78.             }
  79.          }
  80.      }
  81.      canvas.setVector(canvas.rect, write);
  82.      canvas.unlock();
  83. }

Quickly thrown together sand cellular automata - with some tetris shapes.

Posted in BitmapData, Vector, misc | Also tagged , | Leave a comment

Distance Line Gradient

Actionscript:
  1. [SWF(width=600,height=500,frameRate=30)]
  2. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  3. addChild(new Bitmap(canvas));
  4.  
  5. var size:Number=canvas.width*canvas.height;
  6. var w:Number=canvas.width;
  7. var pix:Vector.<uint> = new Vector.<uint>(size);
  8.  
  9. addEventListener(Event.ENTER_FRAME, onLoop);
  10. function onLoop(evt:Event):void {
  11.     canvas.lock();
  12.        
  13.     var i:int = size;
  14.     var x1:Number=mouseX;
  15.     var y1:Number=mouseY;
  16.     var x2:Number=250;
  17.     var y2:Number=250;
  18.     var dx:Number=x2-x1;
  19.     var dy:Number=y2-y1;
  20.     var denom:Number =  1/(dx * dx + dy * dy);
  21.     if (dx==0&&dy==0) {
  22.             x2+=1;
  23.             y2+=1;
  24.             dx=dy=1;
  25.     }
  26.  
  27.     while( --i> -1 ){
  28.         var xp:int= i % w;
  29.         var yp:int = i / w;
  30.         var u:Number = ((xp - x1) * dx + (yp - y1) * dy) * denom;
  31.  
  32.         var closestX:Number;
  33.         var closestY:Number;
  34.         if (u<0) {
  35.             closestX=x1;
  36.             closestY=y1;
  37.         } else if (u> 1) {
  38.             closestX=x2;
  39.             closestY=y2;
  40.         } else {
  41.             closestX=x1+u*dx;
  42.             closestY=y1+u*dy;
  43.         }
  44.         var dfx:Number=closestX-xp;
  45.         var dfy:Number=closestY-yp;
  46.         var d:Number=255-Math.sqrt(dfx*dfx+dfy*dfy);
  47.         if (d<0) d=0;
  48.          pix[i]=uint(d);
  49.     }
  50.     canvas.setVector(canvas.rect, pix);
  51.     canvas.unlock();
  52. }

This didn't come out as interesting as I thought it would for some reason - just used the technique from the last two posts to draw a gradient. Event though it's visually boring, it does show how I went about inlining the function from yesterday... so I figured I'd post it.

Posted in BitmapData, Vector, graphics algorithms | Also tagged , | Leave a comment

Distance Between Point and Line (optimized)

Actionscript:
  1. /**
  2. Original function by Pieter Iserbyt:
  3. http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/DistancePoint.java
  4. from Paul Bourke's website:
  5. http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
  6. */
  7. function pointToLineDist(x1:Number, y1:Number, x2:Number, y2:Number,x3:Number, y3:Number):Number {
  8.     var dx:Number=x2-x1;
  9.     var dy:Number=y2-y1;
  10.     if (dx==0&&dy==0) {
  11.         x2+=1;
  12.         y2+=1;
  13.         dx=dy=1;
  14.     }
  15.     var u:Number = ((x3 - x1) * dx + (y3 - y1) * dy) / (dx * dx + dy * dy);
  16.  
  17.     var closestX:Number;
  18.     var closestY:Number;
  19.     if (u<0) {
  20.         closestX=x1;
  21.         closestY=y1;
  22.     } else if (u> 1) {
  23.         closestX=x2;
  24.         closestY=y2;
  25.     } else {
  26.         closestX=x1+u*dx;
  27.         closestY=y1+u*dy;
  28.     }
  29.     dx=closestX-x3;
  30.     dy=closestY-y3;
  31.     return Math.sqrt(dx * dx +  dy * dy);
  32. }
  33.  
  34. /**
  35. Test out the function
  36. */
  37.  
  38. var dotA:Sprite = dot(100, 100);
  39. var dotB:Sprite = dot(200, 200);
  40. var dotC:Sprite = dot(150, 100, 0x0000FF);
  41. var txt:TextField = TextField(dotC.addChild(new TextField()));
  42. with(txt) x = 5, y = 5, autoSize = "left", selectable = false, mouseEnabled = false;
  43.  
  44. addEventListener(Event.ENTER_FRAME, onLoop);
  45. function onLoop(evt:Event):void {
  46.     graphics.clear();
  47.     graphics.lineStyle(0,0x000000);
  48.     graphics.moveTo(dotA.x, dotA.y);
  49.     graphics.lineTo(dotB.x, dotB.y);
  50.     txt.text = pointToLineDist(dotA.x, dotA.y, dotB.x, dotB.y, dotC.x, dotC.y).toFixed(2);
  51. }
  52.  
  53. // draggable dot
  54. function dot(xp:Number, yp:Number, col:uint = 0xFF0000, rad:Number=4):Sprite {
  55.     var s:Sprite = Sprite(addChild(new Sprite));
  56.     s.x = xp;
  57.     s.y = yp;
  58.     with(s.graphics) beginFill(col), drawCircle(0,0,rad);
  59.     s.buttonMode = true;
  60.     s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
  61.     return s;
  62. }
  63. function onDrag(evt:MouseEvent):void { evt.currentTarget.startDrag() }
  64. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  65. function onUp(evt:MouseEvent):void{stopDrag() }

This is the same as yesterdays post about the distance between a point and a line segment. I just took a few minutes to optimize the function - it runs close to 3X faster now. For more info see yesterdays post.

Posted in Math, graphics algorithms, misc | Also tagged , | 1 Comment

Distance Between Point and Line Segment

Actionscript:
  1. /**
  2. Original function by Pieter Iserbyt:
  3. http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/DistancePoint.java
  4. from Paul Bourke's website:
  5. http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
  6. */
  7. function pointToLineDistance(p1:Sprite, p2:Sprite, p3:Sprite):Number {
  8.     var xDelta:Number = p2.x - p1.x;
  9.     var yDelta:Number = p2.y - p1.y;
  10.     if ((xDelta == 0) && (yDelta == 0)) {
  11.         // p1 and p2 cannot be the same point
  12.         p2.x += 1;
  13.         p2.y += 1;
  14.         xDelta = 1;
  15.             yDelta = 1;
  16.     }
  17.     var u:Number = ((p3.x - p1.x) * xDelta + (p3.y - p1.y) * yDelta) / (xDelta * xDelta + yDelta * yDelta);
  18.     var closestPoint:Point;
  19.     if (u <0) {
  20.         closestPoint = new Point(p1.x, p1.y);
  21.     } else if (u> 1) {
  22.         closestPoint = new Point(p2.x, p2.y);
  23.     } else {
  24.         closestPoint = new Point(p1.x + u * xDelta, p1.y + u * yDelta);
  25.     }
  26.     return Point.distance(closestPoint, new Point(p3.x, p3.y));
  27. }
  28.  
  29. /**
  30. Test out the function
  31. */
  32.  
  33. var dotA:Sprite = dot(100, 100);
  34. var dotB:Sprite = dot(200, 200);
  35. var dotC:Sprite = dot(150, 100, 0x0000FF);
  36. var txt:TextField = TextField(dotC.addChild(new TextField()));
  37. with(txt) x = 5, y = 5, autoSize = "left", selectable = false, mouseEnabled = false;
  38.  
  39. addEventListener(Event.ENTER_FRAME, onLoop);
  40. function onLoop(evt:Event):void {
  41.     graphics.clear();
  42.     graphics.lineStyle(0,0x000000);
  43.     graphics.moveTo(dotA.x, dotA.y);
  44.     graphics.lineTo(dotB.x, dotB.y);
  45.     txt.text = pointToLineDistance(dotA, dotB, dotC).toFixed(2);
  46. }
  47.  
  48. // draggable dot
  49. function dot(xp:Number, yp:Number, col:uint = 0xFF0000, rad:Number=4):Sprite {
  50.     var s:Sprite = Sprite(addChild(new Sprite));
  51.     s.x = xp;
  52.     s.y = yp;
  53.     with(s.graphics) beginFill(col), drawCircle(0,0,rad);
  54.     s.buttonMode = true;
  55.     s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
  56.     return s;
  57. }
  58. function onDrag(evt:MouseEvent):void { evt.currentTarget.startDrag() }
  59. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  60. function onUp(evt:MouseEvent):void{stopDrag() }

Last night I was working late and found myself in need of a way to calculate the distance between a point and a line. After a quick google search I found myself once again on Paul Bourke's extremely useful website. I was in a rush, so I just quickly ported the java code (by Pieter Iserbyt) and wrote this test snippet to make sure it works.

This code could be optimized a bit, but it works nicely.

I needed this for a commercial project, but as I was porting the code I thought of an interesting way to use this code to draw a gradient - may write and post that tomorrow.

Posted in Math, graphics algorithms | Also tagged , | 5 Comments