Category Archives: Graphics

Animate Along Bezier Curve

Actionscript:
  1. var circle:Shape = Shape(addChild(new Shape));
  2. with(circle.graphics) beginFill(0x000000), drawCircle(0,0,5);
  3.  
  4. var bezierPoint:Point = new Point();
  5. function bezier(a:Number, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number):void {
  6.         var b:Number =1-a;
  7.         var pre1:Number=a*a;
  8.         var pre2:Number=2*a*b;
  9.         var pre3:Number=b*b;
  10.         bezierPoint.x = pre1*x1 + pre2*x2  + pre3*x3;
  11.         bezierPoint.y = pre1*y1 + pre2*y2 + pre3*y3;
  12. }
  13.  
  14. var inc:Number = 0;
  15. var theta:Number = 0;
  16.  
  17. addEventListener(Event.ENTER_FRAME, onLoop);
  18. function onLoop(evt:Event):void {
  19.    
  20.      graphics.clear();
  21.      graphics.lineStyle(0,0xFF0000);
  22.      graphics.moveTo(200,200);
  23.      graphics.curveTo(mouseX, mouseY, 400, 200);
  24.  
  25.     theta+= .05;
  26.     inc = .5 + .5*Math.sin(theta);
  27.  
  28.     bezier(inc, 200, 200, mouseX, mouseY, 400, 200);
  29.     circle.x = bezierPoint.x;
  30.     circle.y = bezierPoint.y;
  31. }

The above animates a circle along a quadratic bezier curve. This snippet was written in response to a question spurned by some of the recent bezier posts. I used Math.sin() to animate the circle but you could just as easily use modulus... simply replace lines 25-26 with the following:

Actionscript:
  1. inc += .03;
  2. inc %= 1;

Also posted in bezier, graphics algorithms, motion | Tagged , | 3 Comments

Bezier Skin (smooth curveTo())

Actionscript:
  1. // graphics, vector of xy coords, closed boolean
  2. function bezierSkin(g:Graphics, bez:Vector.<Number>, closed:Boolean = true):void {
  3.     var avg:Vector.<Number> = calcAvgs(bez);
  4.     var i:int, n:int;
  5.     var leng:int = bez.length;
  6.  
  7.     if (closed){
  8.         g.moveTo(avg[0], avg[1]);
  9.         for (i = 2; i <leng; i+=2) {
  10.             n=i+1;
  11.             g.curveTo(bez[i], bez[n], avg[i], avg[n]);
  12.         }
  13.         g.curveTo(bez[0], bez[1], avg[0], avg[1]);
  14.     }else{
  15.         g.moveTo(bez[0], bez[1]);
  16.         g.lineTo(avg[0], avg[1]);
  17.         for (i = 2; i <leng-2; i+=2) {
  18.             n=i+1;
  19.             g.curveTo(bez[i], bez[n], avg[i], avg[n]);
  20.         }
  21.         g.lineTo(bez[ leng - 2], bez[ leng - 1]);
  22.     }
  23. }
  24.  
  25. // create anchor points by averaging the control points
  26. function calcAvgs(v:Vector.<Number>):Vector.<Number> {
  27.     var avg:Vector.<Number> = new Vector.<Number>();
  28.     var leng:int=v.length;
  29.     for (var i:int = 2; i<leng; i+=1) {
  30.         var prev:Number=i-2;
  31.         avg.push( (v[prev] + v[i]) / 2 );
  32.     }
  33.     // close
  34.     avg.push( (v[0] + v[ leng - 2]) / 2 );
  35.     avg.push( (v[1] + v[ leng - 1]) / 2 );
  36.     return avg;
  37. }
  38.  
  39. // test out the functions:
  40.  
  41. graphics.lineStyle(0,0x000000);
  42.  
  43. // draw a very rounded rect
  44. bezierSkin(graphics, Vector.<Number>([100,100,200,100,200,200,100,200]) );
  45.  
  46. // draw a random curve with 10 xy coords
  47. var rnd:Vector.<Number> = new Vector.<Number>();
  48. for (var i:int = 0; i<20; i++) rnd.push(Math.random()*100);
  49. bezierSkin(graphics, rnd);
  50.                        
  51. // erase everything and allow the used to draw a smooth curve with the mouse
  52. stage.addEventListener(MouseEvent.MOUSE_DOWN, onLoop);
  53. var index:int = 0;
  54. var pnts:Vector.<Number> = new Vector.<Number>();
  55.  
  56. function onLoop(evt:MouseEvent):void {
  57.      pnts.push(mouseX);
  58.      pnts.push(mouseY);
  59.    
  60.      graphics.clear();
  61.      graphics.lineStyle(0,0x000000);
  62.      
  63.       // draw a smooth curved line
  64.      bezierSkin(graphics,pnts,false);
  65. }

The above code uses averaging to generate anchor points for curveTo() calls. This is an easy way to always draw smooth curves.

This is an old one that I've seen floating around since the drawing api first came out... but I it's an important snippet, so I figured I'd post it.

Also posted in bezier | Tagged , , | Leave a comment

Gradient Glow

Actionscript:
  1. var colors:Array = [0xFF0000, 0x666699, 0x223322, 0xCCCCDD, 0xFFEEFF];
  2. var alphas:Array = [0, 1, 1, 1, 1];
  3. var ratios:Array = [0, 50, 100, 200, 255]
  4. var filter:GradientGlowFilter = new GradientGlowFilter(0, 0, colors, alphas, ratios, 30, 30, 1, 2, "full", true);
  5.  
  6. var circles:Shape = new Shape();
  7.  
  8.  for (var i:int = 0; i<30; i++){
  9.   with(circles.graphics) beginFill(0xFF0000), drawCircle(Math.random()*500, Math.random()*400,10+Math.random()*40);
  10.  }
  11.  addChild(circles);
  12.  
  13.  circles.filters = [filter];

I don't see GradientGlowFilter used much. But with some tweaking you can probably get some decent stuff out of it.

Posted in Graphics | Tagged , | Leave a comment

Draw Spiral

Actionscript:
  1. stage.frameRate = 30;
  2. var xp:Number = 0;
  3. var yp:Number = 0;
  4. var counter:Number = 0;
  5. graphics.lineStyle(0,0x999999);
  6. graphics.moveTo(200,200);
  7. addEventListener(Event.ENTER_FRAME, onLoop);
  8. function onLoop(evt:Event):void {
  9.     for (var i:int = 0; i <20; i++) {
  10.         counter += .05;
  11.         xp=200 + counter * Math.cos(counter);
  12.         yp=200 + counter * Math.sin(counter);
  13.         graphics.lineTo(xp, yp);
  14.     }
  15.     if (counter> 400) {
  16.         removeEventListener(Event.ENTER_FRAME, onLoop);
  17.     }
  18. }

Draws a spiral over time.

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