Monthly Archives: March 2009

Low Precision Sine and Cosine

Actionscript:
  1. var t:Number=0, cos:Number, sin:Number;
  2.  
  3. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  4. addChild(new Bitmap(canvas));
  5.  
  6. var shape:Shape = new Shape();
  7. with(shape.graphics) beginFill(0x568338, .2), drawCircle(0,0,10);
  8.  
  9. addEventListener(Event.ENTER_FRAME, onLoop);
  10. function onLoop(evt:Event):void {
  11.    
  12.          t += .1;
  13.         // -- low precision sine/cosine
  14.         //always wrap input angle to -PI..PI
  15.         if (t <-3.14159265){
  16.             t += 6.28318531;
  17.         }else{
  18.         if (t>  3.14159265)
  19.             t -= 6.28318531;
  20.         }
  21.        
  22.         //compute sine
  23.         if (t <0){
  24.             sin = 1.27323954 * t + .405284735 * t * t;
  25.         }else{
  26.             sin = 1.27323954 * t - 0.405284735 * t * t;
  27.         }
  28.        
  29.         //compute cosine: sin(t + PI/2) = cos(t)
  30.         t += 1.57079632;
  31.         if (t>  3.14159265){
  32.             t -= 6.28318531;
  33.         }
  34.        
  35.         if (t <0){
  36.             cos = 1.27323954 * t + 0.405284735 * t * t
  37.         }else{
  38.             cos = 1.27323954 * t - 0.405284735 * t * t;
  39.         }
  40.         t -= 1.57079632;
  41.        
  42.         // move the shape
  43.         shape.x = 200 + 100 * cos;
  44.         shape.y = 200 + 100 * sin;
  45.        
  46.         // draw to the canvas
  47.         canvas.draw(shape, shape.transform.matrix);
  48. }

This snippet draws a circle using low precision sine and cosine... you'll notice that its not a perfect looking circle:


Back in January I saw this blog post by Michael Baczynski over at http://lab.polygonal.de/. The blog post describes a technique for fast sine and cosine approximation - (I highly recommend giving it a read - very fun stuff).

It's worth noting that there is a higher precision sine and cosine that will likely draw a better looking circle but will be about half as fast. According to the original post ... the low precision technique is approximately 14x faster than using Math.cos()/Math.sin().

There some other really great posts over at polygonal go check them out.

Posted in Math, motion | Tagged , | 2 Comments

Unique Array Comparison

Actionscript:
  1. function uniqueCompare(arr:Array, compare:Function):void {
  2.     var leng:int = arr.length;
  3.     for (var i:int = 0; i<leng; i++){
  4.         for (var j:int = i + 1; j<leng; j++){
  5.             compare(arr[i], arr[j]);
  6.         }
  7.     }
  8. }
  9.  
  10. var numbers:Array = [1, 2, 3, 4, 5];
  11.  
  12. uniqueCompare(numbers, compareCallback);
  13.  
  14. function compareCallback(a:*, b:*):void {
  15.     trace("compare " + a + " to " + b);
  16. }
  17.  
  18. /*
  19. outputs:
  20. compare 1 to 2
  21. compare 1 to 3
  22. compare 1 to 4
  23. compare 1 to 5
  24. compare 2 to 3
  25. compare 2 to 4
  26. compare 2 to 5
  27. compare 3 to 4
  28. compare 3 to 5
  29. compare 4 to 5
  30. */

This snippet shows a function called uniqueCompare() that compares all elements in an array to all other elements in an array without repeating a comparison.

Posted in arrays, misc | Tagged , | Leave a comment

Object.constructor()

Actionscript:
  1. var Box:Function = {
  2.     constructor : function(color:uint, w:Number, h:Number):void {
  3.         this.color = color;
  4.         this.s = new Shape();
  5.         with(this.s.graphics) beginFill(this.color), drawRect(0,0,w,h);
  6.         addChild(this.s);
  7.        
  8.         this.setLoc = function(x:Number, y:Number):void{
  9.             this.s.x = x;
  10.             this.s.y = y;
  11.        }
  12.     }
  13. }.constructor;
  14.  
  15. var box0:Object = new Box(0xFF0000, 100, 100);
  16.  
  17. box0.setLoc(100, 10);
  18.  
  19. var box1:Object = new Box(0x000000, 50, 50);
  20.  
  21. box1.setLoc(210, 10);

This snippet makes use of Object.constructor() to allow creation of Object instances using the new keyword. This is for fun only, I don't recommend this over actual Classes.

Posted in OOP, dynamic, functions, misc | Tagged , | Leave a comment

Circle of Particles #2

Actionscript:
  1. [SWF(width = 400, height = 400)];
  2. var canvas:BitmapData = new BitmapData(400,400, false, 0x000000);
  3. var eraser:BitmapData = new BitmapData(400,400, true, 0x11000000);
  4. addChild(new Bitmap(canvas));
  5.  
  6. var particles:Array = new Array();
  7. for (var i:int = 0; i <500; i++){
  8.     particles.push(makeParticle());
  9. }
  10.  
  11. addEventListener(Event.ENTER_FRAME, onLoop);
  12. function onLoop(evt:Event):void {
  13.     canvas.copyPixels(eraser, eraser.rect, new Point(0,0), null, null, true);
  14.     for (var i:int = 0; i <particles.length; i++){
  15.         particles[i]();
  16.     }
  17. }
  18.  
  19. function makeParticle():Function {
  20.     var dx:Number, dy:Number;
  21.     var x:Number = 200;
  22.     var y:Number = 200;
  23.     var vx:Number = Math.random() * 4 - 2;
  24.     var vy:Number = Math.random() * 4 - 2;
  25.     var ang:Number;
  26.     return function():void {
  27.               x += vx;
  28.               y += vy;
  29.               dx = 200 - x;
  30.               dy=  200 - y;
  31.                if (Math.sqrt((dx * dx) + (dy * dy))> 130){
  32.                 ang = Math.atan2(dy, dx) / Math.PI * 180;
  33.                  vx = Math.cos(ang);
  34.                  vy = Math.sin(ang);
  35.                }
  36.                canvas.setPixel(x, y, 0xFFFFFF);
  37.     }
  38. }

This is an interesting variation on yesterdays post. The result will looks like this...


Click to view swf...

I also decided to do a processing port of this with 3,000 particles:

Processing Version

The processing version eventually evolved into this:


Click for enlarged version...

Posted in BitmapData, motion, setPixel | Tagged , , | 2 Comments