package af.graphics { import flash.display.Graphics; import flash.geom.Point; public class CatmullRom { /* * @param g The graphics object to draw the curve onto. * @param points An array of flash.geom.Point objects. * @param segments The number of line segments to use between each point on the curve. */ public static function draw(g:Graphics, points:Array, segments:uint=10):void { for (var i:uint=0; i 0) { p1 = points[i-1]; } p2 = points[i]; p3 = points[i+1]; // last point is null at the end of the curve if (i < points.length-2) { p4 = points[i+2]; } drawSegment(g, p1, p2, p3, p4, segments); } } public static function drawSegment(g:Graphics, p1:Point, p2:Point, p3:Point, p4:Point, segments:uint):void { // if either control point isn't provided, use the next closest point on the curve. if (p1 == null) { p1 = p2; } if (p4 == null) { p4 = p3; } g.moveTo(p2.x, p2.y); for (var i:uint=1; i<=segments; i++) { var t:Number = Number(i)/Number(segments); // cast to numbers to ensure we use floating point math var x:Number = equation(t, p1.x, p2.x, p3.x, p4.x); var y:Number = equation(t, p1.y, p2.y, p3.y, p4.y); g.lineTo(x,y); } } protected static function equation(t:Number, p1:Number, p2:Number, p3:Number, p4:Number):Number { // this equation lifted directly from http://steve.hollasch.net/cgindex/curves/catmull-rom.html return 0.5 * ((-p1 + 3*p2 -3*p3 + p4)*t*t*t + (2*p1 -5*p2 + 4*p3 - p4)*t*t + (-p1+p3)*t + 2*p2); } } }