Category Archives: Graphics

drawTriangles() Cubes

Actionscript:
  1. private function addCube(xp:Number, yp:Number, zp:Number, w:Number, h:Number, leng:Number):void{
  2.             var hw:Number = w * 0.5;
  3.             var hh:Number = h * 0.5;
  4.             var hl:Number = leng * 0.5;
  5.             var xA:Number = xp - hw;
  6.             var xB:Number = hw + xp;
  7.             var yA:Number = yp - hh;
  8.             var yB:Number = hh + yp;
  9.             var zA:Number = zp - hl;
  10.             var zB:Number = hl + zp;
  11.             _verts.push(xA, yA, zA,
  12.                         xB, yA, zA,
  13.                         xA, yB, zA,
  14.                         xB, yB, zA,
  15.                         xA, yA, zB,
  16.                         xB, yA, zB,
  17.                         xA, yB, zB,
  18.                         xB, yB, zB);
  19.            
  20.             var index:int = _boxIndex * 8;
  21.             var i0:int = index, i1:int = index + 1, i2:int = index + 2;
  22.             var i3:int = index + 3,  i4:int = index + 4, i5:int = index + 5;
  23.             var i6:int = index + 6, i7:int = index + 7;
  24.             _indices.push(i0, i1, i2,
  25.                           i1, i3, i2,
  26.                           i6, i7, i4,
  27.                           i7, i5, i4,
  28.                           i1, i5, i3,
  29.                           i7, i3, i5,
  30.                           i4, i5, i0,
  31.                           i1, i0, i5,
  32.                           i2, i6, i0,
  33.                           i0, i6, i4,
  34.                           i2, i3, i6,
  35.                           i3, i7, i6);
  36.                          
  37.             _faces.push(new Face(), new Face(), new Face(),
  38.                         new Face(),  new Face(), new Face(),
  39.                         new Face(), new Face(), new Face(),
  40.                         new Face(), new Face(), new Face());
  41.             _uvts.push(Math.random(), Math.random(), 0,
  42.                        Math.random(), Math.random(), 0,
  43.                        Math.random(), Math.random(), 0,
  44.                        Math.random(), Math.random(), 0,
  45.                        Math.random(), Math.random(), 0,
  46.                        Math.random(), Math.random(), 0,
  47.                        Math.random(), Math.random(), 0,
  48.                        Math.random(), Math.random(), 0);
  49.             _boxIndex++;
  50.         }

Lately I've been posting large code snippets... so today I'm highlighting part of a larger snippet - The above code is the heart of a small experiment I created this morning. It sets up a cube for use with drawTraingles().

The rest of the code can be read here:
Cubes3D.as

Have a look at the swf here...


I also put it on wonderfl...

Also posted in 3D, Vector, matrix, motion | Tagged , , | 6 Comments

Matrix Zoom and Pan

Actionscript:
  1. [SWF(width=600, height=600, frameRate=30)]
  2. var sw:Number = stage.stageWidth;
  3. var sh:Number = stage.stageHeight;
  4.  
  5. var s:Shape = Shape(addChild(new Shape()));
  6.  
  7. var scale:Number = 1;
  8. var scaleDest:Number = 1;
  9. var down:Boolean = false;
  10. var dx:Number = 0, dy:Number = 0, time:Number = 0;
  11.  
  12. buttonMode = true;
  13.  
  14. addInstructions();
  15. vectorTexture();
  16.  
  17. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  18. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20.  
  21. function addInstructions():void{
  22.     var instruct:Sprite = Sprite(addChild(new Sprite()));
  23.     with (instruct.graphics) beginFill(0x666666), drawRect(0,0,270, 30);
  24.     instruct.x = instruct.y = 20;
  25.     var txt:TextField = TextField(instruct.addChild(new TextField()));
  26.     txt.defaultTextFormat = new TextFormat("Verdana", 11);
  27.     txt.x = txt.y = 5;
  28.     txt.selectable = false;
  29.     with (txt) textColor = 0xFFFFFF, autoSize = "left", text = "Click and hold to zoom, move mouse to pan";
  30. }
  31.  
  32. function vectorTexture():void{
  33.     var cols:Vector.<uint> = Vector.<uint>([0xFFFFFF, 0x000000]);
  34.     var rnd:Vector.<Number> = new Vector.<Number>(6, true);
  35.    
  36.     for(var i:int = 0 ; i<50; i++){
  37.         with(s.graphics){
  38.             lineStyle(Math.random() * 50 + 2, cols[int(Math.random()*cols.length)]);
  39.             drawCircle(Math.random() * sw, Math.random() * sh, 10 + Math.random() * Math.random() * 400);
  40.         }
  41.     }
  42.     s.graphics.lineStyle(20, 0xCCCCCC);
  43.     s.graphics.drawRect(0, 0,sw, sh);
  44. }
  45.  
  46. function onDown(evt:MouseEvent):void{ down = true; }
  47. function onUp(evt:MouseEvent):void{ down = false; }
  48. function onLoop(evt:Event):void {
  49.    if (down){
  50.      scaleDest *= 1.05;  
  51.      time = 0;
  52.    }else{
  53.      time++;
  54.      // zoom out after 30 iterations
  55.      if (time == 30){
  56.          scaleDest = 1;  
  57.      }
  58.    }
  59.    scale += (scaleDest - scale) / 4;
  60.    if (scale> 10) scale = scaleDest = 10;
  61.    
  62.    dx += (mouseX - dx) / 4;
  63.    dy += (mouseY - dy) / 4;
  64.    if (dx <0) dx = 0;
  65.    if (dy <0) dy = 0;
  66.    if (dx> sw) dx = sw;
  67.    if (dy> sh) dy = sh;
  68.    
  69.    // matrix zoom/pan
  70.    var m:Matrix = s.transform.matrix;
  71.    m.identity();
  72.    m.translate(-dx,-dy);
  73.    m.scale(scale, scale);
  74.    m.translate(dx,dy);
  75.    s.transform.matrix = m;
  76. }

I haven't been by the computer much these last two weeks - been traveling. Going back to nyc tomorrow so I'll go back to posting once a day.

This snippet uses a transformation matrix to zoom in and pan a Sprite instance. For demo purposes I filled the sprite with a few circles - but you'd likely be using this with a vector image of a map, a floor plan or some other graphic that warrants zooming and panning.

Back around flash 7 (I think) before the Matrix class was introduced we used to have to use MovieClip nesting to achieve this effect.


Have a look at the swf...


Also posted in matrix, motion | Tagged , , | Leave a comment

Distance Spring

Actionscript:
  1. [SWF(backgroundColor=0x222222, width=500, height=500)]
  2. var hsw:Number = stage.stageWidth / 2;
  3. var hsh:Number = stage.stageHeight / 2;
  4. var pointNum:int = 800
  5. var points3D:Vector.<Number> = new Vector.<Number>();
  6. var points3Dout:Vector.<Number> = new Vector.<Number>();
  7. var points2D:Vector.<Number> = new Vector.<Number>();
  8. var uvts:Vector.<Number> = new Vector.<Number>();
  9. var sorted:Array = [];
  10. var pnt:Point = new Point();
  11. var m:Matrix3D = new Matrix3D();
  12. var v:Vector3D = new Vector3D();
  13. for (var i:int = 0; i<pointNum; i++){
  14.     v.y = i * 0.7 - 300
  15.     var t =Math.random()*6.28;
  16.     v.x = 200 * Math.cos(i * 2 * Math.PI / 180);
  17.     v.z = 200 * Math.sin(i * 2 * Math.PI / 180);
  18.     v = m.transformVector(v);
  19.     points3D.push(v.x, v.y, v.z);
  20.     points2D.push(0,0);
  21.     uvts.push(0,0,0);
  22.     sorted.push(new Vector3D());
  23. }
  24. points3D.fixed = true;
  25. points2D.fixed = true;
  26. uvts.fixed = true;
  27. var p:PerspectiveProjection = new PerspectiveProjection();
  28. var proj:Matrix3D = p.toMatrix3D();
  29. var dx:Number = 0, dy:Number = 0;
  30. addEventListener(Event.ENTER_FRAME, onLoop);
  31. function onLoop(evt:Event):void {
  32.     var i:int, j:int;
  33.     dx += (mouseX - dx) / 4;
  34.     dy += (mouseY - dy) / 4;
  35.     m.identity();
  36.     m.appendRotation(getTimer() / 4, Vector3D.Y_AXIS);
  37.     m.transformVectors(points3D, points3Dout);
  38.    
  39.     m.identity();
  40.     m.appendRotation(dx, Vector3D.Z_AXIS);
  41.     m.appendRotation(dy, Vector3D.X_AXIS);
  42.     m.appendTranslation(0, 0, 1000);
  43.     m.append(proj);
  44.     Utils3D.projectVectors(m, points3Dout, points2D, uvts);
  45.     for (i = 0, j = 0; i<points2D.length; i+=2, j++){
  46.         sorted[j].x = points2D[i] + hsw;
  47.         sorted[j].y = points2D[i + 1] + hsh;
  48.         sorted[j].z = uvts[j * 3 + 2];
  49.     }
  50.     sorted.sortOn("z", Array.NUMERIC);
  51.     graphics.clear();
  52.     for(i = 0; i<sorted.length; i++){
  53.         var zpos:Number = sorted[i].z * 10000;
  54.         var c:int = zpos * 14;
  55.         graphics.beginFill(c <<16 | c <<8 | c);
  56.         graphics.drawCircle(sorted[i].x, sorted[i].y, zpos);
  57.         graphics.endFill();
  58.     }
  59. }

A variation on some recent posts... this snippet draws a rotating spring made up of 800 particles...

Have a look at the swf...


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

Fake Light w/ UV & Quads

Actionscript:
  1. [SWF(width = 500, height=500, backgroundColor = 0x000000)]
  2. x = stage.stageWidth / 2;
  3. y = stage.stageHeight / 2;
  4. var quadNum:int = 2200;
  5. // standard Vectors for using drawTriangles
  6. var verts:Vector.<Number> = new Vector.<Number>();
  7. var pVerts:Vector.<Number>;
  8. var uvts:Vector.<Number> = new Vector.<Number>();
  9. var indices:Vector.<int> = new Vector.<int>();
  10. // needed for z-sorting
  11. var sortedIndices:Vector.<int>;
  12. var faces:Array = [];
  13. // we'll use this for tranforming points
  14. // and as the transformation matrix for our render
  15. var m:Matrix3D = new Matrix3D();
  16. // plot a quad
  17. var quad:Vector.<Number>;
  18. quad = Vector.<Number>([-10, -10, 0,
  19.                         10, -10, 0,
  20.                         -10, 10, 0,
  21.                         10, 10, 0]);
  22. // temp vect for any transformed quads
  23. var transQuad:Vector.<Number> = new Vector.<Number>();
  24. var i:int;
  25. var inc:int = 0;
  26. for (i = 0; i<quadNum; i++){
  27.     m.identity();
  28.     var s:Number = (int(Math.random()*50) == 1) ? 2 + Math.random()*2 : .1 + Math.random() * 2;
  29.     m.appendScale(s, s, 1);
  30.     m.appendRotation(90, Vector3D.Y_AXIS);
  31.     var mult:Number = 100 + Math.random()*200;
  32.     m.appendTranslation(mult, 0, 0);
  33.     m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
  34.     m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
  35.     m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
  36.     m.transformVectors(quad, transQuad);
  37.     verts = verts.concat(transQuad);
  38.     faces.push(new Vector3D());
  39.     faces.push(new Vector3D());
  40.     var i4:int = i * 4;
  41.     indices.push(0 + i4, 1 + i4, 2 + i4,
  42.                  1 + i4, 3 + i4, 2 + i4);
  43.     mult /= 300;
  44.     uvts.push(mult,mult,0,
  45.               mult+.1,mult,0,
  46.               mult,mult - .1,0,
  47.               mult + .1,mult + .1,0);
  48. }
  49. sortedIndices = new Vector.<int>(indices.length, true);
  50. // create texture
  51. var tex:BitmapData = new BitmapData(400,400,false, 0x000000);
  52. var grad:Shape = new Shape();
  53. var mat:Matrix = new Matrix();
  54. mat.createGradientBox(400,400,0,0,0);
  55. with (grad.graphics){
  56.     beginGradientFill(GradientType.LINEAR, [0xFFFFFF,0x002244], [1, 1], [100, 255], mat);
  57.     drawRect(0,0,400,400);
  58. }
  59. tex.draw(grad);
  60. // create background
  61. mat.createGradientBox(1600,1200,0,-550, 0);
  62. with (grad.graphics){
  63.     beginGradientFill(GradientType.RADIAL, [0x000000, 0x001133], [1, 1], [0, 255], mat);
  64.     drawRect(0,0,500,500);
  65. }
  66. grad.x = -stage.stageWidth/2
  67. grad.y = -stage.stageHeight/2;
  68. addChild(grad);
  69. // triangles will be drawn to this
  70. var render:Shape = Shape(addChild(new Shape()));
  71. // fix all vector lengths
  72. verts.fixed = true, uvts.fixed = true, indices.fixed = true
  73. pVerts = new Vector.<Number>(verts.length/3 * 2, true);
  74. // we need these if we want perspective
  75. var persp:PerspectiveProjection = new PerspectiveProjection();
  76. persp.fieldOfView = 45;
  77. // projection matrix
  78. var proj:Matrix3D = persp.toMatrix3D();
  79. var dx:Number = 0, dy:Number = 0;
  80. addEventListener(Event.ENTER_FRAME, onLoop);
  81. function onLoop(evt:Event):void {
  82.     dx += (mouseX - dx) / 4;
  83.     dy += (mouseY - dy) / 4;
  84.     m.identity();
  85.     m.appendRotation(dy, Vector3D.X_AXIS);
  86.     m.appendRotation(dx, Vector3D.Y_AXIS);
  87.     m.appendTranslation(0,0,800);
  88.     m.append(proj);
  89.     Utils3D.projectVectors(m, verts, pVerts, uvts);
  90.     var face:Vector3D;
  91.     inc = 0;
  92.     for (var i:int = 0; i<indices.length; i+=3){
  93.         face = faces[inc];
  94.         face.x = indices[i];
  95.         face.y = indices[int(i + 1)];
  96.         face.z = indices[int(i + 2)];
  97.         var i3:int = i * 3;
  98.         face.w = (uvts[int(face.x*3 + 2)] + uvts[int(face.y*3 + 2)] + uvts[int(face.z*3 + 2)]) * 0.333333;
  99.         inc++;
  100.     }
  101.     faces.sortOn("w", Array.NUMERIC);
  102.     inc = 0;
  103.     for each (face in faces){
  104.         sortedIndices[inc++] = face.x;
  105.         sortedIndices[inc++] = face.y;
  106.         sortedIndices[inc++] = face.z;
  107.     }
  108.     render.graphics.clear();
  109.     render.graphics.beginBitmapFill(tex, null, false, false);
  110.     render.graphics.drawTriangles(pVerts, sortedIndices, uvts, TriangleCulling.NEGATIVE);
  111. }

Expanding again on the z-sorting demos from the last few days - this snippet uses UV coords and a gradient to create something that vaguely resembles a light. Unlike the previous demos, the 3D cluster in this snippet is made up of quads - requiring a slight adjustment to the depth calculation.


Have a look at the swf...

I also posted the code over at wonderfl.net...

Also posted in 3D, Vector, matrix, misc, sortOn | Tagged , , , | 2 Comments