New Release of NaturalGUI. NET Filled Arc Animation

Filled Arc’s anyone?

February 28th, 2005

I’ve always loved arc’s, especially in images like this one.

I remember seeing Sci-fi imagery from the 60’s and 70’s with patterns similar to these and I always wondered where they first originated.

Anyway, after playing with Ric Ewing’s advanced drawing API methods for a while I decided I wanted a means of drawing these filled arc shapes, and the draw wedge method was tantalizingly close, so I had a little play with it this afternoon and here’s what I came up with.

The code is fully AS2.0 compliant so you can just drop it into a DrawingMethods class if you have one. There’s nothing wrong with just running it from the timeline either if you’re so inclined.

I’ve also put a little example code at the bottom which will draw images like the one above. I’m also working on a little animated demo which I’ll post up quite soon.

Enjoy.

 /*
 Function: drawFilledArc

 Description:
 Draws filled Arc shapes (with interior and exterior radius)

 Author: Jason Milkins jason@mentalaxis.com | <http ://www.mentalaxis.com>

 Version: 1.0

 Note:
 Based on code by Ric Ewing </http><http ://www.ricewing.com>

 Parameters:
 mc - MovieClip target to draw in
 x, y - center point of the wedge.
 startAngle - starting angle in degrees.
 arc - sweep of the wedge. Negative values draw clockwise.
 exteriorRadius - exterior radius of wedge.
 interiorRadius - interior radius of wedge.

 Note:
 Comments formatted for NaturalDocs
 */
 function drawFilledArc (mc, x, y, startAngle, arc, exteriorRadius, interiorRadius ) : Void
 {
  // if yRadius is undefined, yRadius = radius
  // Init vars
  var segAngle_a, segAngle_b, theta_a, theta_b, angle, angleMid, segs, ax, ay, bx, by, cx, cy, dx, dy;
  // limit sweep to reasonable numbers
  if (Math.abs (arc) > 360)
  {
   arc = 360;
  }
  // Flash uses 8 segments per circle, to match that, we draw in a maximum
  // of 45 degree segments. First we calculate how many segments are needed
  // for our arc.
  segs = Math.ceil (Math.abs (arc) / 45);
  // Now calculate the sweep of each segment.
  segAngle_a = arc / segs
  segAngle_b = -arc / segs;
  // The math requires radians rather than degrees. To convert from degrees
  // use the formula (degrees/180)*Math.PI to get radians.
  theta_a = - (segAngle_a / 180) * Math.PI;
  theta_b = - (segAngle_b / 180) * Math.PI;
  // convert angle startAngle to radians
  angle = - (startAngle / 180) * Math.PI;
  // draw the curve in segments no larger than 45 degrees.
  if (segs > 0)
  {
   // draw a line from the end of the interior curve to the start of the exterior curve
   ax = x + Math.cos (startAngle / 180 * Math.PI) * exteriorRadius;
   ay = y + Math.sin ( - startAngle / 180 * Math.PI) * exteriorRadius;
   mc.moveTo (ax, ay);
   // Loop for drawing exterior  curve segments
   for (var i = 0; i < segs; i ++)
   {
    angle += theta_a;
    angleMid = angle - (theta_a / 2);
    bx = x + Math.cos (angle) * exteriorRadius;
    by = y + Math.sin (angle) * exteriorRadius;
    cx = x + Math.cos (angleMid) * (exteriorRadius / Math.cos (theta_a / 2));
    cy = y + Math.sin (angleMid) * (exteriorRadius / Math.cos (theta_a / 2));
    mc.curveTo (cx, cy, bx, by);
   }
   // draw a line from the end of the exterior curve to the start of the interior curve

   startAngle += arc;
   angle = - (startAngle / 180) * Math.PI;
   // draw the interior (subtractive) wedge
   // draw a line from the center to the start of the interior curve
   dx = x + Math.cos (startAngle / 180 * Math.PI) * interiorRadius;
   dy = y + Math.sin ( - startAngle / 180 * Math.PI) * interiorRadius;
   mc.lineTo (dx, dy);
   // Loop for drawing interior curve segments
   for (var i = 0; i < segs; i ++)
   {
    angle += theta_b;
    angleMid = angle - (theta_b / 2);
    bx = x + Math.cos (angle) * interiorRadius;
    by = y + Math.sin (angle) * interiorRadius;
    cx = x + Math.cos (angleMid) * (interiorRadius / Math.cos (theta_b / 2));
    cy = y + Math.sin (angleMid) * (interiorRadius / Math.cos (theta_b / 2));
    mc.curveTo (cx, cy, bx, by);
   }
   mc.lineTo (ax, ay);
  }
 }

And here’s the demo code…

my_mc = _root.createEmptyMovieClip ("poop", 100);
my_mc.i = 0;
my_mc.inc = 20;
my_mc.cenX = 350;
my_mc.cenY = 350;
innerRad = 20 + (Math.random () * 150);

my_mc.onEnterFrame = function ()
{
 if (Math.random () * 100 < 10)
 {
  my_mc.clear ();
  for (n = 0; n < 10; n ++)
  {
   innerRad = 20 + (Math.random () * 150)
   my_mc.lineStyle(2, 0x000000, 10);
   my_mc.beginFill (0xAA0000, 20 + (Math.random () * 60));
   drawFilledArc (my_mc, my_mc.cenX, my_mc.cenY, Math.random () * 360 , - Math.random () * 360 , innerRad, innerRad + (Math.random () * 40) + 4);
   my_mc.endFill ();
  }
 }
}

can you Digg it? can you Digg it? is it del.icio.us? is it del.icio.us?

Category: General

1 Comment Add your own

  • 1. Jason Milkins  |  February 28th, 2009 at 8:23 am

    Should’ve mentioned, paste both bits of code onto the timeline (frame 1) and test the flash movie…

    Re run the movie for a new pattern.

Leave a Comment

You must be logged in to post a comment .

Trackback this post  |  Subscribe to the comments via RSS Feed

Clicky Web Analytics