Monthly Archives: June 2009

x and y Coordinates in 1D Array / Vector

Actionscript:
  1. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  2. addChild(new Bitmap(canvas));
  3. var pix:Vector.<uint>=canvas.getVector(canvas.rect);
  4.  
  5. canvas.lock();
  6. for (var i:int = 0; i<300; i++) {
  7.     var xp:int=50+i;
  8.     var yp:int=50+i/2;
  9.     // target x and y coords in 1D array
  10.     pix[xp+yp*400]=0xFFFFFF;
  11. }
  12. canvas.setVector(canvas.rect, pix);
  13. canvas.unlock();

This snippet shows how to target x and y coordinates in a 1D Array / Vector. This can be useful sometimes when working with setVector().

This is sort of like re-inventing setPixel().... and for that reason is kind of pointless - that said, it's interesting to know. I first learned about this technique from using processing.

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

IGraphicsData Example

Actionscript:
  1. // note the high framerate for testing purposes
  2. [SWF(width = 800, height = 600, frameRate=60)]
  3. // red, yellow, blue
  4. var fills:Vector.<IGraphicsData> = Vector.<IGraphicsData>([new GraphicsSolidFill(0xFF0000),  new GraphicsSolidFill(0xFFCC00), new GraphicsSolidFill(0x0033FF)]);
  5.  
  6. var stroke:IGraphicsData = new GraphicsStroke();
  7.  
  8. var cmds:Vector.<int> = new Vector.<int>();
  9. var ci:int = 0;
  10. var dat:Vector.<Number> = new Vector.<Number>();
  11. var di:int = 0;
  12. var igraph:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
  13. var ig:int  = 0;
  14. var path:Vector.<GraphicsPath> = new Vector.<GraphicsPath>();
  15. var boxNum:int = 1500;
  16. var locX:Vector.<Number> = new Vector.<Number>(boxNum);
  17. var locY:Vector.<Number> = new Vector.<Number>(boxNum);
  18. var velX:Vector.<Number> = new Vector.<Number>(boxNum);
  19. var velY:Vector.<Number> = new Vector.<Number>(boxNum);
  20. var cols:int = 50;
  21. for (var i:int = 0; i<boxNum; i++){
  22.     path[i] = new GraphicsPath(new Vector.<int>(), new Vector.<Number>());
  23.     path[i].winding = GraphicsPathWinding.NON_ZERO;
  24.     var theta:Number = i * Math.PI/180;
  25.     var sin:Number = Math.cos(theta);
  26.     var cos:Number =  Math.sin(theta);
  27.     var r:Number = Math.random()*100;
  28.     var vr:Number = r * 0.05;
  29.     velX[i] = vr * cos;
  30.     velY[i] = vr * sin;
  31.     locX[i] = 400 + r * cos;
  32.     locY[i] = 300 + r * sin;
  33. }
  34.  
  35. // box vars
  36. var xp:Number, yp:Number, size:Number, hs:Number;
  37. // corners
  38. var x0:Number, y0:Number, x1:Number, y1:Number;
  39.  
  40. addEventListener(Event.ENTER_FRAME, onLoop);
  41. function onLoop(evt:Event):void {
  42.     graphics.clear();
  43.     ig = 0;
  44.     for (i= 0; i<boxNum; i++){
  45.         // inline function:
  46.         locX[i] += velX[i];
  47.         locY[i] += velY[i];
  48.         xp = locX[i];
  49.         yp = locY[i];
  50.         if (xp <0 || xp> 800){
  51.             velX[i] *= -1;
  52.         }
  53.         if (yp <0 || yp> 600){
  54.             velY[i] *= -1;
  55.         }
  56.         size = 10 + i % 10;
  57.         hs = size * 0.5;
  58.         x0 = xp - hs, y0 = yp - hs;
  59.         x1 = xp + hs, y1 = yp + hs;
  60.         ci = 0;
  61.         di = 0;
  62.         cmds = path[i].commands;
  63.         dat = path[i].data;
  64.         // GraphicsPathCommand.MOVE_TO
  65.         cmds[ci++] = 1;
  66.         dat[di++] = x0 , dat[di++] = y0;
  67.         // GraphicsPathCommand.LINE_TO
  68.         cmds[ci++] = 2;
  69.         dat[di++] = x1 , dat[di++] = y0;
  70.         // GraphicsPathCommand.LINE_TO
  71.         cmds[ci++] = 2;
  72.         dat[di++] = x1 , dat[di++] = y1;
  73.         // GraphicsPathCommand.LINE_TO
  74.         cmds[ci++] = 2;
  75.         dat[di++] = x0 , dat[di++] = y1;
  76.         // end inline function
  77.          
  78.         path[i].commands = cmds;
  79.         path[i].data = dat;
  80.         igraph[ig++] = fills[i % 3];
  81.         igraph[ig++] = path[i];
  82.     }
  83.     // everything is drawn with one function call
  84.     graphics.drawGraphicsData(igraph);
  85. }

I haven't spent much time with IGraphicsData. It's a very cool feature and I think its going to take me awhile to realize its full potential. Since I have to start somewhere I decided to write this snippet to show that it is rather fast. I also recalled reading some benchmark info for the new fp10 graphics stuff over at bytearray.org.... pretty nice info there...

This snippet is pretty optimized, there are a few areas (such as the recurring population of the cmds Vector) that could be optimized more but are left this way for SOME flexibility.

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

Vectorpark Style Cylinder

Actionscript:
  1. const TWO_PI:Number = Math.PI * 2;
  2. const PI_HALF_PI:Number = Math.PI + Math.PI / 2;
  3. x = stage.stageWidth / 2;
  4. y = stage.stageHeight / 2;
  5. var runCylinder:Function = makeCylinder(0,0, 100, 300, 0xFF0000, 0xFFCC00);
  6. var dx:Number = 0;
  7. var dy:Number = 0;
  8. addEventListener(Event.ENTER_FRAME, onLoop);
  9. function onLoop(evt:Event):void {
  10.     dx += (mouseX / 50 - dx) / 4;
  11.     dy += (mouseY - dy) / 4;
  12.     runCylinder(dx, dy);
  13. }
  14. function makeCylinder(x:Number, y:Number, size:Number, length:Number, colA:uint, colB:uint):Function{
  15.     var s:Sprite = Sprite(addChild(new Sprite()));
  16.     s.x = x;
  17.     s.y = y;
  18.     var acol:uint = colB;
  19.     var bcol:uint = colB;
  20.     var halfLength:Number = length / 2;
  21.     var capA:Sprite = Sprite(s.addChild(new Sprite()));
  22.     var box:Sprite = Sprite(s.addChild(new Sprite()));
  23.     var w:Number = size * 2;
  24.     var h:Number = length;
  25.     with (box.graphics)  beginFill(colA), drawRect(-w/2, -h/2, w,h);
  26.     var capB:Sprite = Sprite(s.addChild(new Sprite()));
  27.     return function(theta:Number, rot:Number){
  28.         theta %= TWO_PI;
  29.         if (theta <0){
  30.             theta = TWO_PI - -theta;
  31.         }
  32.         var scale:Number = Math.cos(theta);
  33.         if (theta> 1.57){
  34.             acol = colA;
  35.             s.addChild(capB);
  36.             bcol = colB;
  37.         } else {
  38.             acol = colB;
  39.             bcol = colA;
  40.             s.addChild(capA);
  41.         }
  42.         if (theta> PI_HALF_PI){
  43.             acol = colB;
  44.             bcol = colA;
  45.             s.addChild(capA);
  46.         }
  47.        
  48.         var sin:Number = Math.sin(theta);
  49.         box.scaleY = sin;
  50.         capA.y = halfLength * sin;
  51.         capB.y = -capA.y;
  52.         with(capA.graphics) clear(), beginFill(acol), scaleYcircle(capA.graphics,size, scale);
  53.         with(capB.graphics) clear(), beginFill(bcol), scaleYcircle(capB.graphics,size, scale);
  54.         s.rotation = rot;
  55.     }
  56. }
  57. // original circle function by senocular (www.senocular.com) from here http://www.actionscript.org/forums/showthread.php3?s=&threadid=30328
  58. // circle that can be scaled on the y axis
  59. function scaleYcircle(g:Graphics, r:Number, s:Number = 1):void {
  60.     var c1:Number = r * (Math.SQRT2 - 1);
  61.     var c2:Number = r * Math.SQRT2 / 2;
  62.     var rs:Number = r * s, c1s:Number = c1 * s, c2s:Number = c2 * s;
  63.     var x_r:Number =  -r, y_r:Number = -rs, x_c2:Number =  -c2;
  64.     var y_c2:Number =  -c2s, x_c1:Number =  -c1, y_c1:Number =  -c1s
  65.     g.moveTo(r, 0), g.curveTo(r, c1s, c2, c2s);
  66.     g.curveTo(c1, rs, 0, rs), g.curveTo(x_c1,rs, x_c2, c2s);
  67.     g.curveTo(x_r, c1s, x_r, 0), g.curveTo(x_r,y_c1,x_c2,y_c2);
  68.     g.curveTo(x_c1,y_r,0,y_r), g.curveTo(c1,y_r,c2,y_c2);
  69.     g.curveTo(r,y_c1,r,0);
  70. }

This is similar to the last post I did.... inspired by some of the great stuff over at VectorPark.com... this snippet creates a 3D cylinder out of two circles and a box...

Posted in 3D, Graphics | Tagged , , | Leave a comment

Vectorpark Style Hemisphere

Actionscript:
  1. const TWO_PI:Number = Math.PI * 2;
  2. const PI_HALF_PI:Number = Math.PI + Math.PI / 2;
  3. x = stage.stageWidth / 2;
  4. y = stage.stageHeight / 2;
  5.  
  6. var runHemisphere:Function = makeHemisphere(0,0, 100,0xFF0000, 0xFFCC00);
  7. var dx:Number = 0;
  8. var dy:Number = 0;
  9.  
  10. addEventListener(Event.ENTER_FRAME, onLoop);
  11. function onLoop(evt:Event):void {
  12.     dx += (mouseX / 50 - dx) / 4;
  13.     dy += (mouseY - dy) / 4;
  14.     runHemisphere(dx, dy);
  15. }
  16. function makeHemisphere(x:Number, y:Number, size:Number, colA:uint, colB:uint):Function{
  17.     var s:Sprite = Sprite(addChild(new Sprite()));
  18.     s.x = x;
  19.     s.y = y;
  20.     var bg:Sprite = Sprite(s.addChild(new Sprite()));
  21.    
  22.     with (bg.graphics) clear(), beginFill(colA), halfCircle(bg.graphics, 0,0 , size);
  23.     var scol:uint = colB;
  24.     var slice:Sprite = Sprite(s.addChild(new Sprite()));
  25.     return function(theta:Number, rot:Number){
  26.          theta %= TWO_PI;
  27.         if (theta <0){
  28.             theta = TWO_PI - -theta;
  29.         }
  30.         var scale:Number = Math.cos(theta);
  31.         if (theta> 1.57){
  32.             scol = colA;
  33.         } else {
  34.             scol = colB;
  35.         }
  36.         if (theta> Math.PI){
  37.             bg.rotation = 180;
  38.         }else{
  39.             bg.rotation = 0;
  40.         }
  41.         if (theta> PI_HALF_PI){
  42.             scol = colB;
  43.         }
  44.         with(slice.graphics) clear(), beginFill(scol), scaleYcircle(slice.graphics,size, scale);
  45.         s.rotation = rot;
  46.     }
  47. }
  48. // original circle function by senocular (www.senocular.com) from here http://www.actionscript.org/forums/showthread.php3?s=&threadid=30328
  49. function halfCircle(g:Graphics, x:Number,y:Number,r:Number):void {
  50.     var c1:Number = r * (Math.SQRT2 - 1);
  51.     var c2:Number = r * Math.SQRT2 / 2;
  52.     var xr:Number = x + r, yr:Number = y + r;
  53.     var x_r:Number = x - r, yc1:Number = y + c1;
  54.     var yc2:Number = y + c2, xc1:Number = x + c1, xc2:Number = x + c2;
  55.     var x_c1:Number = x - c1;
  56.     g.moveTo(xr, y);
  57.     g.curveTo(xr, yc1, xc2, yc2);
  58.     g.curveTo(xc1, yr, x, yr);
  59.     g.curveTo(x - c1,yr, x - c2, yc2);
  60.     g.curveTo(x_r, yc1, x_r, y);
  61. }
  62. // circle that can be scaled on the y axis
  63. function scaleYcircle(g:Graphics, r:Number, s:Number = 1):void {
  64.     var c1:Number = r * (Math.SQRT2 - 1);
  65.     var c2:Number = r * Math.SQRT2 / 2;
  66.     var rs:Number = r * s, c1s:Number = c1 * s, c2s:Number = c2 * s;
  67.     var x_r:Number =  -r, y_r:Number = -rs, x_c2:Number =  -c2;
  68.     var y_c2:Number =  -c2s, x_c1:Number =  -c1, y_c1:Number =  -c1s
  69.     g.moveTo(r, 0), g.curveTo(r, c1s, c2, c2s);
  70.     g.curveTo(c1, rs, 0, rs), g.curveTo(x_c1,rs, x_c2, c2s);
  71.     g.curveTo(x_r, c1s, x_r, 0), g.curveTo(x_r,y_c1,x_c2,y_c2);
  72.     g.curveTo(x_c1,y_r,0,y_r), g.curveTo(c1,y_r,c2,y_c2);
  73.     g.curveTo(r,y_c1,r,0);
  74. }

The above snippet draws a 3D hemisphere using a technique I first saw at vectorpark.com. Vectorpark.com has been around for years and it's an amazing site... if you've never seen it before I highly recommend spending some time there...

When I decided to post the half-circle snippet yesterday... I knew I would be writing this today. It's one of those things I've always thought about doing, but never gotten around to. I show vectorpark.com to my animation class (almost no coding in that class) and we emulate some of the 3D techniques for simple primitives with pure timeline animation. The above is the first time I've tried to emulate one of these techniques with code.

I was pleasantly surprised when visiting vectorpark.com this morning... Patrick Smith has posted some new work there. Really excellent stuff...

UPDATE:
Katopz converted this to a doc class and put it up on wonderfl...

Posted in 3D, Graphics | Tagged , , | 6 Comments