Category Archives: matrix

Another Matrix.transformPoint()

Actionscript:
  1. [SWF(width = 628, height=500)]
  2. var trans:Matrix = new Matrix();
  3. var pnt:Point = new Point();
  4. x = stage.stageWidth / 2;
  5. y = stage.stageHeight / 2;
  6. addEventListener(Event.ENTER_FRAME, onLoop);
  7. function onLoop(evt:Event):void {
  8.     graphics.clear();
  9.     graphics.lineStyle(10, 0x000000, 1, false, LineScaleMode.NORMAL, CapsStyle.SQUARE);
  10.     pnt.x = 0;
  11.     pnt.y = 0;
  12.     trans.identity();
  13.     trans.translate(15,15);
  14.     trans.rotate(mouseX/10 * Math.PI / 180);
  15.     graphics.moveTo(pnt.x, pnt.y);
  16.     for (var i:int = 0; i<12; i++){
  17.         pnt = trans.transformPoint(pnt);
  18.         graphics.lineTo(pnt.x, pnt.y);
  19.     }
  20. }

I was thinking about processing and OpenGL today... I always really enjoyed using matrix stuff, working with the matrix stack, using push() and pop() etc... Understanding how to use matrices is pretty important when your doing advanced graphics in actionscript. If you haven't messed with matrices, this snippet is a good place to start. It uses Matrix.transformPoint() to draw a series of connected lines that are controlled by the x location of the mouse. Back before flash 8, this kind of thing was usually done using trig or MovieClip nesting...

I posted another snippet on this topic awhile back.

Also posted in motion | 2 Comments

Utils3D.projectVectors() Lathe

Actionscript:
  1. [SWF(width = 500, height = 500, backgroundColor = 0x000000)]
  2. var halfWidth:Number = stage.stageWidth / 2;
  3. var halfHeight:Number = stage.stageHeight / 2;
  4. var loc:Vector.<Number>;
  5.  
  6. graphics.lineStyle(0, 0xFF0000);
  7. graphics.moveTo(halfWidth, 0);
  8. graphics.lineTo(halfWidth, stage.stageHeight);
  9. graphics.moveTo(0, halfHeight);
  10. graphics.lineTo(stage.stageWidth, halfHeight);
  11.  
  12. var line:Shape = Shape(addChild(new Shape()));
  13. line.x = halfWidth;
  14.  
  15. var idle:Function = function(){};
  16. var currentMode:Function = idle;
  17. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  18. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onDown(evt:MouseEvent):void{
  21.     if (contains(frame)){
  22.         removeChild(frame);
  23.         currentMode = idle;
  24.         line.graphics.clear();
  25.         return;
  26.     }
  27.     loc = new Vector.<Number>();
  28.     line.graphics.lineStyle(0,0xFFFFFF);
  29.     line.x = halfWidth
  30.     line.y = halfHeight;
  31.     line.graphics.moveTo(line.mouseX, line.mouseY);
  32.     currentMode = captureLocs;
  33.     canvas.fillRect(canvas.rect, 0x000000);
  34. }
  35. function onUp(evt:MouseEvent):void{
  36.     if (currentMode == idle) return;
  37.     setupLathe();
  38.     currentMode = showLathe;
  39. }
  40.  
  41. function onLoop(evt:Event):void{
  42.     currentMode();
  43. }
  44. function captureLocs():void{
  45.     loc.push(line.mouseX);
  46.     loc.push(line.mouseY);
  47.     loc.push(0);
  48.     line.graphics.lineTo(line.mouseX, line.mouseY);
  49. }
  50. /**
  51.  -- Lathe Stuff:
  52. */
  53. var canvas:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight,false, 0x000000);
  54. var frame:Bitmap = new Bitmap(canvas);
  55. var dx:Number=0;
  56. var dy:Number=0;
  57.  var matrix:Matrix3D = new Matrix3D();
  58. var pVerts:Vector.<Number>;
  59. var uvts:Vector.<Number>;
  60. function setupLathe():void{
  61.     addChild(frame);
  62.     pVerts =  new Vector.<Number>();
  63.     uvts = new Vector.<Number>();
  64.     var nVerts:Vector.<Number> = new Vector.<Number>();
  65.     var tVerts:Vector.<Number> = new Vector.<Number>();
  66.     matrix.identity();
  67.     var step:Number = 2;
  68.     for (var i:int = 0; i <360; i+=step){
  69.         matrix.appendRotation(step,Vector3D.Y_AXIS);
  70.         matrix.transformVectors(loc, tVerts);
  71.         nVerts = nVerts.concat(tVerts);
  72.     }
  73.     loc = nVerts.concat();
  74. }
  75. function showLathe():void{
  76.     dx += (mouseX - dx)/4;
  77.     dy += (mouseY - dy)/4;
  78.     matrix.identity();
  79.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  80.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  81.     matrix.appendTranslation(halfWidth, halfHeight, 0);
  82.     Utils3D.projectVectors(matrix, loc, pVerts, uvts);
  83.     canvas.lock();
  84.     canvas.fillRect(canvas.rect, 0x000000);
  85.     var leng:int = pVerts.length;
  86.     for (var i:int = 0; i<leng; i+=2){
  87.         canvas.setPixel( pVerts[i], pVerts[i + 1], 0xFFFFFF);
  88.     }
  89.     canvas.unlock();
  90. }

This snippet allows you to create 3D lathe shapes by drawing a 2D line. This is done using Utils3D.projectVectors() and Matrix.transformVectors().

Have a look at the swf here...

Also posted in 3D, BitmapData, Math, Vector, graphics algorithms, setPixel | Tagged , , | 3 Comments

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.

Also posted in BitmapData, Math, Vector, color, graphics algorithms, pixel manipulation | Tagged , | Leave a comment

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...

Also posted in 3D, BitmapData, Vector, setPixel | Tagged , | 3 Comments