Monthly Archives: May 2009

drawPath() Boxes

Actionscript:
  1. const TWO_PI:Number = Math.PI * 2;
  2. var boxNum:int = 3000;
  3. var pointNum:int = boxNum * 10;
  4. var rot:Vector.<Number> = new Vector.<Number>();
  5. var posX:Vector.<Number> = new Vector.<Number>();
  6. var posY:Vector.<Number> = new Vector.<Number>();
  7. var velX:Vector.<Number> = new Vector.<Number>();
  8. var velY:Vector.<Number> = new Vector.<Number>();
  9. var scale:Vector.<Number> = new Vector.<Number>();
  10. var rotSpeed:Vector.<Number> = new Vector.<Number>();
  11. var geometry:Vector.<Number> = new Vector.<Number>();
  12. var cmds:Vector.<int> = new Vector.<int>();
  13.  
  14. var stageWidth:Number = stage.stageWidth;
  15. var stageHeight:Number = stage.stageHeight;
  16.  
  17. populateGeom();
  18. function populateGeom():void{
  19.     for (var i:int = 0; i<pointNum; i+=10){
  20.         posX.push(Math.random() * stageWidth);
  21.         posY.push(Math.random() * stageHeight);
  22.         velX.push(Math.random()*4 - 2);
  23.         velY.push(Math.random()*4 - 2);
  24.         scale.push(Math.random() * 1 + .2);
  25.         rot.push(Math.random() * TWO_PI);
  26.         rotSpeed.push(Math.random() * 0.2 - 0.1);
  27.         geometry[i] = 0;
  28.         geometry[i + 1] = 0;
  29.         cmds.push(1);
  30.         geometry[i + 2] =  0;
  31.         geometry[i + 3] =  0;
  32.         cmds.push(2);
  33.         geometry[i + 4] =  0;
  34.         geometry[i + 5] =  0;
  35.         cmds.push(2);
  36.         geometry[i + 6] = 0;
  37.         geometry[i + 7] =  0;
  38.         cmds.push(2);
  39.         geometry[i + 8] =  0;
  40.         geometry[i + 9] =  0;
  41.         cmds.push(2);
  42.     }
  43. }
  44.  
  45. function run():void{
  46.     var inc:int = 0;
  47.     var xt:Number, yt:Number, s:Number, r:Number, rs:Number;
  48.     var cos:Number, sin:Number;
  49.     var cosN:Number, cosP:Number, sinN:Number, sinP:Number;
  50.     for (var i:int = 0; i<pointNum; i+=10){
  51.         xt = posX[inc] += velX[inc];
  52.         yt = posY[inc] += velY[inc];
  53.        
  54.         if (xt <0 || xt> stageWidth){
  55.             velX[inc] *= -1;
  56.         }
  57.         if (yt <0 || yt> stageHeight){
  58.             velY[inc] *= -1;
  59.         }
  60.          
  61.         s = scale[inc];
  62.         r = rot[inc] += rotSpeed[inc];
  63.         inc++;
  64.          
  65.         cos = Math.cos(r);
  66.         sin = Math.sin(r);
  67.        
  68.         cosN = -10  * cos;
  69.         cosP = 10  * cos
  70.         sinN = -10 * sin;
  71.         sinP = 10 * sin;
  72.         geometry[i] = xt + (cosN - sinN) * s;
  73.         geometry[i + 1] = yt + (cosN + sinN) * s;
  74.         geometry[i + 2] = xt + (cosP - sinN) * s;
  75.         geometry[i + 3] = yt + (cosN + sinP) * s;
  76.         geometry[i + 4] = xt + (cosP - sinP) * s;
  77.         geometry[i + 5] = yt + (cosP + sinP) * s;
  78.         geometry[i + 6] = xt + (cosN - sinP) * s;
  79.         geometry[i + 7] = yt + (cosP + sinN) * s;
  80.         geometry[i + 8]  = geometry[i];
  81.         geometry[i + 9]  = geometry[i + 1];
  82.     }
  83. }
  84.  
  85. addEventListener(Event.ENTER_FRAME, onLoop);
  86. function onLoop(evt:Event):void {
  87.      run();
  88.      graphics.clear();
  89.      graphics.beginFill(0x000000);
  90.      graphics.drawPath(cmds, geometry,GraphicsPathWinding.NON_ZERO);
  91.      graphics.endFill();
  92. }

I was messing with drawPath() today and did this snippet as a sort of performance test... the code isn't fully optimized but it's clear that drawPath() is rather fast. I wish that there were beginFill() and lineStyle() drawing commands that worked with it though... oh yeah, that's what IGraphicsData is for...

Posted in Graphics, motion | Tagged , | Leave a comment

Bounds 3 Ways

Actionscript:
  1. // make a complex poly and position it randomly
  2. var poly:Sprite = Sprite(addChild(new Sprite()));
  3. poly.graphics.lineStyle(3, 0xFF0000);
  4. poly.graphics.beginFill(0x00FF00);
  5. for (var i:int = 0; i<10; i++) {
  6.     poly.graphics.lineTo(Math.random()*100 - 50, Math.random()*100 - 50);
  7. }
  8. poly.x=Math.random()*stage.stageWidth;
  9. poly.y=Math.random()*stage.stageHeight;
  10.  
  11. // get bound information:
  12.  
  13. // is in pixels (whole numbers)
  14. trace("pixelBounds: ", poly.transform.pixelBounds);
  15. // doesn't include stroke width
  16. trace("getBounds: ", poly.getBounds(this));
  17. // includes stroke width
  18. trace("getRect: ", poly.getRect(this));

Three different ways to get the boundaries of a DisplayObject.

Posted in DisplayObject | Tagged , | 1 Comment

More Messy Code

Actionscript:
  1. var size:Number = 800;
  2. var canvas:BitmapData = new BitmapData(size,size,false, 0x000000);
  3. addChild(new Bitmap(canvas, "auto", true));
  4.  
  5. scaleX = scaleY = .5;
  6. var pix:Number = size * size;
  7. var scale:Number = 1/(size/3);
  8.  
  9. for (var i:Number = 0; i<pix; i++){
  10.        var xp:Number = (i % size);
  11.        var yp:Number = int(i / size);
  12.        var xt:Number = xp * scale;
  13.        var yt:Number = yp * scale;
  14.        var ca:Number =  (Math.abs(Math.tan(yt) * Math.pow(Math.sin(xt),3)) * 100 ) % 155;
  15.        var cb:Number =  (Math.abs(Math.tan(xt) * Math.pow(Math.sin(yt),3)) * 100)  % 155;
  16.        ca|= cb;
  17.        canvas.setPixel(xp, yp,  ca <<16 | ca <<8 | ca);
  18. }

Another messy code snippet that I e-mailed to myself at some point...

Try replacing line 16 with some of these variations:

ca &= cb;
ca += cb;
ca -= cb;
ca ^= cb;
ca %= cb

Posted in BitmapData, misc, pixel manipulation, setPixel | Tagged , | Leave a comment

QuickBox2D Documentation

I finally finished the QuickBox2D documentation. Check it out here.

You can download QuickBox2D and see a few example code snippets on the QuickBox2D page. Should have a tutorial on that page in the next couple of days.

Posted in Box2D, QuickBox2D, motion | Tagged , | 5 Comments

Instantiate and Set Properties

Actionscript:
  1. function create(obj:Class, props:Object):*{
  2.     var o:* = new obj();
  3.     for (var p:String in props){
  4.         o[p] = props[p];
  5.     }
  6.     return o;
  7. }
  8.  
  9. // test out the function
  10.  
  11. var txt:TextField = create(TextField, {x:200, y:100, selectable:false, text:"hello there", textColor:0xFF0000, defaultTextFormat:new TextFormat("_sans", 20)});
  12. addChild(txt);
  13.  
  14. var s:Sprite = Sprite(addChild(create(Sprite, {x:100, y:100, rotation:45, alpha:.5})));
  15.  
  16. with (s.graphics) beginFill(0xFF0000), drawRect(-20,-20,40,40);
  17.  
  18. var blur:BlurFilter = create(BlurFilter, {blurX:2, blurY:8, quality:1});
  19.  
  20. s.filters = [blur];

This snippet shows a function called create() that takes two arguments. The first argument is the name of a class to instantiate. The second is an Object with a list of properties to set on a newly created instance of the class (referenced in the first argument).

This could be particularly useful for TextFields which for some reason have no arguments in their constructor.

This will currently only work for classes that have either all optional constructor arguments or no constructor arguments.

Posted in dynamic, functions, one-liners, properties | Tagged , | Comments closed

Messy Code

Actionscript:
  1. var xp:Number=0,yp:Number=0;
  2. var r:Number=0,t:Number=0;
  3. var speed:Number=.01;
  4. var scale:Number=10;
  5. var shape:Shape = Shape(addChild(new Shape()));
  6. shape.x=stage.stageWidth/2;
  7. shape.y=stage.stageHeight/2;
  8. shape.graphics.lineStyle(0,0x000000);
  9.  
  10. var s:Number=100;
  11. var range:Number=.2;
  12. var b:Number=20;
  13. var a:Number =b*range;
  14.  
  15. addEventListener(Event.ENTER_FRAME, onLoop);
  16. function onLoop(evt:Event):void {
  17.     range=.2;
  18.     b=20;
  19.     a=b*range;
  20.     t=0;
  21.     shape.graphics.clear();
  22.     shape.graphics.lineStyle(0,0);
  23.     for (var i:int = 0; i<6000; i++) {
  24.         var sin:Number=Math.cos(t*int(mouseY/20));
  25.         r =  Math.sqrt(40 * b * (b - a * (Math.pow(sin, int(mouseX/20)))));
  26.         xp=r*Math.cos(t);
  27.         yp=r*Math.sin(t);
  28.  
  29.         if (t==0) {
  30.             shape.graphics.lineStyle(0, 0);
  31.             shape.graphics.moveTo(xp, yp);
  32.         } else {
  33.             shape.graphics.lineTo(xp, yp);
  34.         }
  35.         t+=speed;
  36.         if (t> (2 * Math.PI + speed)) {
  37.             range+=.3;
  38.             a=b*range;
  39.             t=0;
  40.         }
  41.     }
  42. }

This is an example of raw messy code that draws some interesting shapes. I was waiting somewhere with my laptop a few weeks back and I wrote this and e-mailed this to myself - it's completely unoptimized and unedited.

I was working on documentation for QuickBox2D today but didn't finish it - so I posted this instead. I hope to finish the docs for tomorrow...

Posted in misc | Tagged , | Leave a comment

Distance Render

Actionscript:
  1. var verts:Vector.<Number> = new Vector.<Number>();
  2. var pVerts:Vector.<Number> = new Vector.<Number>();
  3. var uvts:Vector.<Number> = new Vector.<Number>();
  4.  
  5. var hs:Number = 2.3;
  6. var step:Number = 0.04;
  7.  
  8. var tVerts:Vector.<Number> = new Vector.<Number>();
  9. var rVerts:Vector.<Number> = new Vector.<Number>();
  10. var matrix:Matrix3D = new Matrix3D();
  11. matrix.identity();
  12. matrix.appendRotation(45,Vector3D.Y_AXIS);
  13. matrix.appendRotation(45,Vector3D.X_AXIS);
  14. var inc:int = 0;
  15. var i:Number, j:Number, k:Number;
  16. i = hs;
  17. while( i> -hs){
  18.     j = hs;
  19.     while(j> -hs){
  20.         k = hs;
  21.         while(k> -hs){
  22.             tVerts[inc] = -i;
  23.             inc++
  24.             tVerts[inc] = -j;
  25.             inc++
  26.             tVerts[inc] = -k;
  27.             inc++
  28.             k -= step;
  29.         }
  30.         j -= step;
  31.     }
  32.     i -= step;
  33. }
  34.  
  35. matrix.transformVectors(tVerts, rVerts);
  36.  
  37. var vinc:int = 0;
  38. inc = 0
  39. var R:Number = 1.5;
  40. var r:Number = .5;
  41. for (i= -hs; i<hs; i+=step){
  42.     for (j = -hs; j<hs; j+=step){
  43.         for (k = -hs; k<hs; k+=step){
  44.             var vx:Number = rVerts[inc] ;
  45.             inc++
  46.             var vy:Number = rVerts[inc]  ;
  47.             inc++
  48.             var vz:Number=  rVerts[inc] ;
  49.             inc++
  50.             var s:Number = Math.pow(vx  * vx  + vy * vy + vz * vz + R*R - r * r, 2) - 4 * (R * R)*(vx * vx + vy * vy);
  51.             if (s <0 && s> -.5){
  52.                 verts[vinc] = (i * 50);
  53.                 vinc++
  54.                 verts[vinc] = (j * 50);
  55.                 vinc++
  56.                 verts[vinc] = (k * 50);
  57.                 vinc++
  58.                   inc += int((hs - k) / step) * 3;
  59.                   k = hs;
  60.              }
  61.         }
  62.     }
  63. }
  64.  
  65. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  66. addChild(new Bitmap(canvas));
  67. render();
  68. function render():void{
  69.     matrix.identity();
  70.     matrix.appendTranslation(200, 200, 0);
  71.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  72.     canvas.lock();
  73.     canvas.fillRect(canvas.rect, 0x000000);
  74.     var inc:int = 2;
  75.     var c:int = 0;
  76.     var r:Rectangle = new Rectangle();
  77.     r.width = r.height = 2;
  78.     for (var i:int = 0; i<pVerts.length; i+=2){
  79.           r.x = pVerts[i];
  80.           r.y = pVerts[i + 1];
  81.           c = Math.max(0,100 - verts[inc]);
  82.           canvas.fillRect(r, c <<16 | c <<8 | c);
  83.           inc += 3;
  84.     }
  85.     canvas.unlock();
  86. }

This snippet uses some of the techniques from the last few posts to create a distance render - this renders the implicit equation for a torus.

Posted in BitmapData, Math, Vector, color, graphics algorithms, matrix, pixel manipulation | Tagged , | Leave a comment

Array.push() Vector.push() Optimization

Actionscript:
  1. var tVerts:Vector.<Number> = new Vector.<Number>();
  2. var inc:int = 0;
  3. var t:Number, i:Number, j:Number, k:Number;
  4.  
  5.  // fast way
  6. t = getTimer();
  7. for (i= -2; i<2; i+=.03){
  8.     for (j = -2; j<2; j+=.03){
  9.         for (k = -2; k<2; k+=.03){
  10.             tVerts[inc] = i;
  11.             inc++;
  12.             tVerts[inc] = j;
  13.             inc++;
  14.             tVerts[inc]= k;
  15.             inc++;
  16.         }
  17.     }
  18. }
  19. trace(getTimer() - t);
  20.  
  21. tVerts  = new Vector.<Number>();
  22.  
  23. // slow way
  24. t = getTimer();
  25. for (i= -2; i<2; i+=.03){
  26.     for (j = -2; j<2; j+=.03){
  27.         for (k = -2; k<2; k+=.03){
  28.  
  29.             tVerts.push(i, j, k);
  30.         //  tVerts.push(j);
  31.         //  tVerts.push(k);
  32.         }
  33.     }
  34. }
  35. trace(getTimer() - t);

Today I needed to populate a Vector in the above manner... populating the vector using push() was quite slow in this case because (among other reasons) push() is a method call. I was curious how much faster populating the Vector without push would be... so I wrote this snippet - in this case it was significantly faster - took less than a third of the time. You can run this snippet to see what kind of results you get.

It's important to note that this nested for loop could be optimized further but I wanted to focus on the push() optimization alone.

Warning

The most HORRIBLE thing about testing the speed of ActionScript code is that you CANNOT rely on the debug player to test optimizations. Always use the release version of the flash player. The debug player will give unusual (usually slower) results...

Posted in Vector, arrays | Tagged , | 1 Comment

Parametric UV Surface

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2. var verts:Vector.<Number> = new Vector.<Number>();
  3. var pVerts:Vector.<Number> = new Vector.<Number>();
  4. var uvts:Vector.<Number> = new Vector.<Number>();
  5. var sqrt2:Number = Math.sqrt(2)
  6. var pi:Number = Math.PI;
  7. var pi23:Number= 2 * Math.PI / 3;
  8. var step:Number= pi / 50;
  9. for (var u:Number = -pi; u<pi; u+=step) {
  10.     for (var v:Number = -pi; v<pi; v+=step) {
  11.         // from here http://local.wasp.uwa.edu.au/~pbourke/geometry/hexatorus/
  12.         var px = Math.sin(u) / Math.abs(sqrt2+ Math.cos(v))
  13.         var py = Math.sin(u+pi23) / Math.abs(sqrt2 +Math.cos(v + pi23))
  14.         var pz = Math.cos(u-pi23) / Math.abs(sqrt2 +Math.cos(v - pi23))
  15.         verts.push(px * 50);
  16.         verts.push(py * 50);
  17.         verts.push(pz * 50);
  18.     }
  19. }
  20. var brush:BitmapData=new BitmapData(3,2,true,0x41FFFFFF);
  21. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  22. addChild(new Bitmap(canvas));
  23. var dx:Number=0;
  24. var dy:Number=0;
  25. addEventListener(Event.ENTER_FRAME, onLoop);
  26. function onLoop(evt:Event):void {
  27.     dx += (mouseX - dx)/4;
  28.     dy += (mouseY - dy)/4;
  29.     matrix.identity();
  30.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  31.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  32.     matrix.appendTranslation(200, 200, 0);
  33.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  34.     canvas.lock();
  35.     canvas.fillRect(canvas.rect, 0x000000);
  36.     var p = new Point();
  37.     for (var i:int = 0; i<pVerts.length; i+=2) {
  38.         p.x = pVerts[i];
  39.         p.y = pVerts[i+1];
  40.         canvas.copyPixels(brush, brush.rect, p, null, null, true);
  41.     }
  42.     canvas.unlock();
  43. }

More 3D shapes inspired by (taken from) Paul Bourke's website. I figured I should probably add a parametric 3D surface to this set of posts - so I chose to plot the Triaxial Hexatorus. It's important to note that U and V go from -PI to PI.

I googled Triaxial Hexatorus and stumbled upon a great papervision demo that creates meshes using parametric equations - it also morphs between shapes.

I also noticed that I don't need to populate the uvts or pVerts Vectors with zeros - seems to work fine without doing that.

Posted in 3D, BitmapData, Math, Vector, graphics algorithms, pixel manipulation | Tagged , | Leave a comment

Wormhole

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

Yet another variation on the post from the last two days. This one plots something resembling a wormhole - I was randomly tweaking the equation for a sphere and stumbled upon this...

Posted in 3D, BitmapData, Math, Vector, graphics algorithms, pixel manipulation | Tagged , | Leave a comment