Monthly Archives: April 2009

Utils3D.projectVectors() & 100,000 pixels

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2.  
  3. const PARTICLE_NUM:int = 100000;
  4. var verts:Vector.<Number> = new Vector.<Number>();
  5. var pVerts:Vector.<Number> = new Vector.<Number>();
  6. var uvts:Vector.<Number> = new Vector.<Number>();
  7.  
  8. for (var i:int = 0; i<PARTICLE_NUM; i++){
  9.     verts.push(Math.random()*250 - 125);
  10.     verts.push(Math.random()*250 - 125);
  11.     verts.push(Math.random()*250 - 125);
  12.    
  13.     pVerts.push(0), pVerts.push(0);
  14.     uvts.push(0), uvts.push(0), uvts.push(0);
  15. }
  16.  
  17. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  18. addChild(new Bitmap(canvas));
  19. var dx:Number=0;
  20. var dy:Number=0;
  21.  
  22. addEventListener(Event.ENTER_FRAME, onLoop);
  23. function onLoop(evt:Event):void {
  24.  
  25.     dx += (mouseX - dx)/4;
  26.     dy += (mouseY - dy)/4;
  27.    
  28.     matrix.identity();
  29.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  30.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  31.     matrix.appendTranslation(200, 200, 0);
  32.    
  33.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  34.    
  35.     canvas.lock();
  36.     canvas.fillRect(canvas.rect, 0x000000);
  37.         var leng:int = pVerts.length;
  38.     for (var i:int = 0; i<leng; i+=2){
  39.         canvas.setPixel( pVerts[i], pVerts[i + 1], 0xFFFFFF);
  40.     }
  41.     canvas.unlock();
  42. }

The above shows an easy way to use Utils3D.projectVectors() to move some pixels around in 3D. Since the 3D math is done behind the scenes by the flash player it runs quite fast...

Posted in 3D, BitmapData, Vector, matrix, setPixel | Tagged , | 3 Comments

Vector.sortOn()

Actionscript:
  1. var a:Vector.<Sprite> = new Vector.<Sprite>();
  2.  
  3. trace("unsorted");
  4. for (var i:int = 0; i<10; i++){
  5.     var s:Sprite = new Sprite();
  6.     s.x = int(Math.random()*100);
  7.     a.push(s);
  8.     trace(s.x);
  9. }
  10.  
  11. quickSortOn(a, "x", 0, a.length-1);
  12.  
  13. trace("sorted");
  14. for (i= 0; i<10; i++){
  15.     trace(a[i].x);
  16. }
  17.  
  18. // modified code from kirupa.com
  19. // http://www.kirupa.com/developer/actionscript/quickSort.htm
  20. function quickSortOn(a:Vector.<Sprite>, prop:String, left:int, right:int):void {
  21.     var i:int = 0, j:int = 0, pivot:Sprite, tmp:Sprite;
  22.     i=left;
  23.     j=right;
  24.     pivot = a[Math.round((left+right)*.5)];
  25.     while (i<=j) {
  26.         while (a[i][prop]<pivot[prop]) i++;
  27.         while (a[j][prop]>pivot[prop]) j--;
  28.         if (i<=j) {
  29.             tmp=a[i];
  30.             a[i]=a[j];
  31.             i++;
  32.             a[j]=tmp;
  33.             j--;
  34.         }
  35.     }
  36.     if (left<j)  quickSortOn(a, prop, left, j);
  37.     if (i<right) quickSortOn(a, prop, i, right);
  38. }
  39. /* outputs something like:
  40. unsorted
  41. 26
  42. 33
  43. 20
  44. 63
  45. 7
  46. 68
  47. 75
  48. 39
  49. 67
  50. 53
  51. sorted
  52. 7
  53. 20
  54. 26
  55. 33
  56. 39
  57. 53
  58. 63
  59. 67
  60. 68
  61. 75
  62. */

This demo is my first quick stab at using at a sortOn() function for the Vector class. It sorts a Vector of Sprites by their x property.

Recently there were a few times when I was prototyping ideas and suddenly realized that I needed to change my Vector to an Array because I needed to use sortOn().(If you don't already know, there is no built in sortOn() method for the Vector class). In the past I spent some time with sorting algorithms, bubble, insertion etc... so I knew I could pretty easily write my own sortOn(), but I also realized that a generic implementation wouldn't be easy/possible without loosing the type of the Vector. What I mean is, if you have a Vector of Sprites, you need a sorting method that takes a Vector.< Sprite > type as an argument (as seen above), if you have a Vector of TextFields you need a Vector.< TextField > type as an argument. You could of course use a generic type, but this kind of defeats the purpose of using a vector in the first place...

I will likely post a revised version of this in the near future with a slightly improved implementation of QuickSort. I haven't spent that much time with this, but If I recall correctly this is not the ideal implementation. I ported this code from a nice Kirupa tutorial and modified it to sort based on a property...

Posted in Object, Vector, arrays, associative arrays, sortOn | Tagged , | 3 Comments

Babylonian Method for Square Root

Actionscript:
  1. var xn:Number = 1;
  2. var xn1:Number = 0
  3. var square:Number =39;
  4.  
  5. trace("find the sqrt of ", square);
  6. trace("Math.sqrt: ", Math.sqrt(square))
  7.  
  8. // no starting approximation, just try up to 35 iterations
  9. for(var i:int = 0; i<35; i++){
  10.     xn1 = .5 * (xn  + square / xn);
  11.     if (xn1== xn){
  12.         trace("other sqrt: ", xn1);
  13.         break;
  14.     }
  15.     xn = xn1;
  16. }
  17. /*outputs
  18. find the sqrt of  39
  19. Math.sqrt:  6.244997998398398
  20. other sqrt:  6.244997998398398
  21. */

I was reading about calculating square roots - not for speed optimization purposes, just to see some of the different ways to go about it. The above snippet uses the Babylonian method to find the square root of a number. I left out the first step of guessing at the square root... so this snippet is by no means efficient...

Posted in Math | Tagged , | 2 Comments

Supershapes / Superformula

Actionscript:
  1. // Superformula (equations from):
  2. // http://www.geniaal.be/downloads/AMJBOT.pdf
  3. // http://en.wikipedia.org/wiki/Superformula
  4. const TWO_PI:Number = Math.PI * 2;
  5. function superShape(a:Number, b:Number, m:Number, n1:Number, n2:Number, n3:Number, pnt:Point, scale:Number):void{
  6.     var r:Number = 0
  7.     var p:Number = 0;
  8.     var xp:Number = 0, yp:Number = 0;
  9.     while(p <= TWO_PI){
  10.         var ang:Number = m * p / 4;
  11.         with(Math){
  12.             r = pow(pow(abs(cos(ang) / a), n2) + pow(abs(sin(ang) / b), n3),-1/n1);
  13.             xp = r * cos(p);
  14.             yp = r * sin(p);
  15.         }
  16.         p += .01;
  17.         canvas.setPixel(pnt.x + xp *scale, pnt.y + yp * scale,  0xFFFFFF);
  18.      }
  19. }
  20. // test it out:
  21. var canvas:BitmapData = new BitmapData(700,600,false, 0x000000);
  22. addChild(new Bitmap(canvas, "auto", true));
  23.  
  24. superShape(1, 1, 5, 23, 23, 23, new Point(100,80), 30);
  25. superShape(1, 1, 5, 13, 13, 3, new Point(200,80), 30);
  26. superShape(1, 1, 8, 3, 13, 3, new Point(300,80), 30);
  27. superShape(10,8, 16, 30, 13, 3, new Point(450,80), 30);
  28. superShape(1,1, 1, .5, .5, .5, new Point(100,190), 100);
  29.  
  30. for (var i:int = 0; i <150; i++){
  31.   superShape(1,1, 2, 1+i/800, 4, 8-i * .1, new Point(550,350), 50);
  32. }
  33. for (i = 0; i <20; i++){
  34.   superShape(1.1,1.2, 6, 2 + i , 4, 9 - i, new Point(200,350), 50);
  35. }

The above snippet demos a function that will draw Supershapes using the Superformula...

From wikipedia:
The Superformula appeared in a work by Johan Gielis. It was obtained by generalizing the superellipse, named and popularized by Piet Hein...

Here is the result of the above code:


You can read more about the Superformula here in the original paper by Gielis.

wikipedia entry...

3d Supershapes by Paul Bourke

Posted in Math, graphics algorithms, misc, setPixel | Tagged , | Leave a comment