ulfben

FastDraw.as

Nov 24th, 2016
66
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.ulfben.utils {
  2.     import flash.display.*;
  3.     import flash.geom.*;
  4.  
  5.     public class FastShapes {
  6.         public static const HORIZONTAL_LINE:String = "FastShapes.horizontal";
  7.         public static const VERTICAL_LINE:String = "FastShapes.vertical";
  8.         public static const TO_RAD:Number = (Math.PI / 180);
  9.         public static const TO_DEG:Number = (180 / Math.PI);
  10.         public static const PI2:Number = Math.PI * 2;
  11.         public static const HALF_PI:Number = Math.PI * 0.5;
  12.         public static const QUARTER_PI:Number = Math.PI * 0.25;
  13.         public static const EIGHTH_PI:Number = Math.PI * 0.125;
  14.  
  15.         /**
  16.          * Creates look up tables for sin and cos, to reduce function calls.
  17.          * index = int(angle * (2048/2PI))
  18.          */    
  19.         public static var sCosLUT:Vector.<Number> = new Vector.<Number>(0x800, true);
  20.         public static var sSinLUT:Vector.<Number> = new Vector.<Number>(0x800, true);
  21.         public static function initLUTs():void  {
  22.             for (var i:int = 0; i < 0x800; ++i)
  23.             {
  24.                 sCosLUT[i & 0x7FF] = Math.cos(i * 0.00306796157577128245943617517898); // 0.003067... is 2PI/2048
  25.                 sSinLUT[i & 0x7FF] = Math.sin(i * 0.00306796157577128245943617517898);
  26.             }
  27.         }
  28.         public static function sinLUT(x:Number):Number{
  29.             return sSinLUT[(x * 325.94932345220164765467394738691) & 2047]; // 325.949... is 2048/2PI
  30.         }
  31.         public static function cosLUT(x:Number):Number{
  32.             return sCosLUT[((x * 325.94932345220164765467394738691) & 2047)]; //325.949... is 2048/2PI
  33.         }
  34.  
  35.         public static function sinCoarse(x:Number):Number {
  36.             if (x < -3.14159265) { //always wrap input angle to -PI..PI
  37.                 x += 6.28318531;
  38.             } else if (x > 3.14159265) {
  39.                 x -= 6.28318531;
  40.             }
  41.             return (x < 0) ? (1.27323954 * x + .405284735 * x * x) : (1.27323954 * x - 0.405284735 * x * x);
  42.         }
  43.  
  44.         public static function cosCoarse(x:Number):Number {
  45.             if (x < -3.14159265) { //always wrap input angle to -PI..PI
  46.                 x += 6.28318531;
  47.             } else if (x > 3.14159265) {
  48.                 x -= 6.28318531;
  49.             }
  50.             x += 1.57079632; // //compute cosine: sin(x + PI/2) = cos(x)
  51.             if (x > 3.14159265) {
  52.                 x -= 6.28318531;
  53.             }
  54.             return (x < 0) ? (1.27323954 * x + 0.405284735 * x * x) : (1.27323954 * x - 0.405284735 * x * x);
  55.         }
  56.  
  57.         public static function sinFine(x:Number):Number {
  58.             if(x < -3.14159265) {
  59.                     x += 6.28318531;
  60.             } else if(x > 3.14159265) {
  61.                     x -= 6.28318531;
  62.             }
  63.             x = (x < 0.0) ? (1.27323954 * x + .405284735 * x * x) : (1.27323954 * x - 0.405284735 * x * x)
  64.             return (x < 0.0) ? (0.225 * (x *-x - x) + x) : (0.225 * (x * x - x) + x)
  65.         }
  66.    
  67.         public static function cosFine(x:Number): Number {
  68.             if(x < -3.14159265) {
  69.                 x += 6.28318531;
  70.             } else if(x > 3.14159265) {
  71.                 x -= 6.28318531;
  72.             }
  73.             x += 1.57079632;
  74.             if(x > 3.14159265) {
  75.                 x -= 6.28318531;
  76.             }
  77.             x = (x < 0.0) ? (1.27323954 * x + .405284735 * x * x) : (1.27323954 * x - 0.405284735 * x * x)
  78.             return (x < 0.0) ? (0.225 * (x *-x - x) + x) : (0.225 * (x * x - x) + x)
  79.         }
  80.  
  81.         public static var testCos:Function = cosFine; // cosLUT, cosCoarse, cosFine
  82.         public static var testSin:Function = sinFine; // sinLUT,  sinCoarse, sinFine
  83.  
  84.  
  85.         public function FastShapes() {
  86.             throw new ArgumentError("The FastShapes Class cannot be instanicated.");
  87.         }
  88.  
  89.         /***
  90.          * drawCircle
  91.          * Since Flash Player 8 there is an internal drawCircle-method. Before that I
  92.          * used this. At some point they should be benchmarked against eachother.
  93.          */
  94.         public static function drawCircle(target:Graphics, x:Number, y:Number, r:Number):void {
  95.             var tan:Number = Math.tan(EIGHTH_PI) * r;
  96.             var sin:Number = testSin(QUARTER_PI) * r;
  97.             target.moveTo(x + r, y);
  98.             target.curveTo(r + x, tan + y, sin + x, sin + y);
  99.             target.curveTo(tan + x, r + y, x, r + y);
  100.             target.curveTo((-tan) + x, r + y, (-sin) + x, sin + y);
  101.             target.curveTo(-r + x, tan + y, -r + x, y);
  102.             target.curveTo(-r + x, (-tan) + y, (-sin) + x, (-sin) + y);
  103.             target.curveTo((-tan) + x, -r + y, x, -r + y);
  104.             target.curveTo(tan + x, -r + y, sin + x, (-sin) + y);
  105.             target.curveTo(r + x, (-tan) + y, r + x, y);
  106.             target.moveTo(x, y);
  107.         }
  108.  
  109.         // wobbleFactor in percent. 0.04-0.08 is a good default range.
  110.         public static function handDrawLine(target:Graphics, startPoint:Point, endPoint:Point, wobbleFactor:Number = 0.05):void {
  111.             var wobble:Number = Point.distance(startPoint, endPoint) * wobbleFactor;
  112.             var r1:Number = Math.random();
  113.             var r2:Number = Math.random();
  114.             var xfactor:Number = Math.random() > 0.5 ? wobble : -wobble;
  115.             var yfactor:Number = Math.random() > 0.5 ? wobble : -wobble;
  116.             var control1:Point = new Point((endPoint.x - startPoint.x) * r1 + startPoint.x + xfactor, (endPoint.y - startPoint.y) * r1 + startPoint.y + yfactor);
  117.             var control2:Point = new Point((endPoint.x - startPoint.x) * r2 + startPoint.x - xfactor, (endPoint.y - startPoint.y) * r2 + startPoint.y - yfactor);
  118.             target.moveTo(startPoint.x, startPoint.y);
  119.             target.cubicCurveTo(control1.x, control1.y, control2.x, control2.y, endPoint.x, endPoint.y);
  120.         }
  121.  
  122.        
  123.          // Draws a dashed line from the point x1,y1 to the point x2,y2
  124.         public static function drawDash(target:Graphics, x1:Number, y1:Number, x2:Number, y2:Number, dashLength:Number = 5, spaceLength:Number = 5):void {
  125.             var x:Number = x2 - x1;
  126.             var y:Number = y2 - y1;
  127.             var hyp:Number = Math.sqrt((x) * (x) + (y) * (y));
  128.             var units:Number = hyp / (dashLength + spaceLength);
  129.             var invertedUnits:Number = 1 / units;
  130.             var dashSpaceRatio:Number = dashLength / (dashLength + spaceLength);
  131.             var dashX:Number = (x * invertedUnits) * dashSpaceRatio;
  132.             var spaceX:Number = (x * invertedUnits) - dashX;
  133.             var dashY:Number = (y * invertedUnits) * dashSpaceRatio;
  134.             var spaceY:Number = (y * invertedUnits) - dashY;
  135.  
  136.             target.moveTo(x1, y1);
  137.             while (hyp > 0) {
  138.                 x1 += dashX;
  139.                 y1 += dashY;
  140.                 hyp -= dashLength;
  141.                 if (hyp < 0) {
  142.                     x1 = x2;
  143.                     y1 = y2;
  144.                 }
  145.                 target.lineTo(x1, y1);
  146.                 x1 += spaceX;
  147.                 y1 += spaceY;
  148.                 target.moveTo(x1, y1);
  149.                 hyp -= spaceLength;
  150.             }
  151.             target.moveTo(x2, y2);
  152.         }
  153.  
  154.        
  155.         //Draws an arc from the starting position of x,y.      
  156.         public static function drawArc(target:Graphics, x:Number, y:Number, radius:Number, arc:Number, startAngle:Number = 0, yRadius:Number = 0):void {
  157.             if (yRadius == 0) {
  158.                 yRadius = radius;
  159.             }
  160.             var segAngle:Number, theta:Number, halfTheta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;
  161.             if (FastShapes.abs(arc) > 360) {
  162.                 arc = 360; // no sense in drawing more than is needed :)
  163.             }
  164.             // Flash uses 8 segments per circle, to match that, we draw in a maximum of 45 degree segments.
  165.             segs = FastShapes.ceil(FastShapes.abs(arc) / 45);
  166.             segAngle = arc / segs;
  167.             theta = -(segAngle) * FastShapes.TO_RAD;
  168.             angle = -(startAngle) * FastShapes.TO_RAD;
  169.             ax = x - testCos(angle) * radius;
  170.             ay = y - testSin(angle) * yRadius;
  171.             if (segs > 0) {
  172.                 target.moveTo(x, y);
  173.                 halfTheta = theta * 0.5;
  174.                 var radiusCosHalfTheta:Number = radius / testCos(halfTheta);
  175.                 var yRadiusCosHalfTheta:Number = yRadius / testCos(halfTheta);
  176.                 for (var i:int = 0; i < segs; ++i) {
  177.                     angle += theta;
  178.                     angleMid = angle - halfTheta;
  179.                     bx = ax + testCos(angle) * radius;
  180.                     by = ay + testSin(angle) * yRadius;
  181.                     cx = ax + testCos(angleMid) * radiusCosHalfTheta;
  182.                     cy = ay + testSin(angleMid) * yRadiusCosHalfTheta;
  183.                     target.curveTo(cx, cy, bx, by);
  184.                 }
  185.             }
  186.         }
  187.  
  188.         // draws pie shaped wedges.  Could be employed to draw pie charts.     
  189.         public static function drawWedge(target:Graphics, x:Number, y:Number, radius:Number, arc:Number, startAngle:Number = 0, yRadius:Number = 0):void {
  190.             if (yRadius == 0) {
  191.                 yRadius = radius;
  192.             }
  193.             if (FastShapes.abs(arc) > 360) {
  194.                 arc = 360;
  195.             }
  196.             target.moveTo(x, y);
  197.             var segAngle:Number, theta:Number, halfTheta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;
  198.             // Flash uses 8 segments per circle, to match that, we draw in a maximum of 45 degree segments.
  199.             segs = FastShapes.ceil(FastShapes.abs(arc) / 45);
  200.             segAngle = arc / segs;
  201.             theta = -(segAngle) * FastShapes.TO_RAD;
  202.             angle = -(startAngle) * FastShapes.TO_RAD;
  203.             // draw the curve in segments no larger than 45 degrees.
  204.             if (segs > 0) {
  205.                 ay = y + testSin(angle) * yRadius; //NOTE: angle is negative!
  206.                 ax = x + testCos(-angle) * radius; //NOTE: -angle == positive value here!
  207.                 target.lineTo(ax, ay);
  208.                 halfTheta = theta * 0.5;
  209.                 var radiusCosHalfTheta:Number = radius / testCos(halfTheta);
  210.                 var yRadiusCosHalfTheta:Number = yRadius / testCos(halfTheta);
  211.                 for (var i:int = 0; i < segs; ++i) {
  212.                     angle += theta;
  213.                     angleMid = angle - halfTheta;
  214.                     bx = x + testCos(angle) * radius;
  215.                     by = y + testSin(angle) * yRadius;
  216.                     cx = x + testCos(angleMid) * radiusCosHalfTheta;
  217.                     cy = y + testSin(angleMid) * yRadiusCosHalfTheta;
  218.                     target.curveTo(cx, cy, bx, by);
  219.                 }
  220.                 target.lineTo(x, y);
  221.             }
  222.         }
  223.  
  224.        
  225.         // draws a star shaped polygon.    
  226.         public static function drawStar(target:Graphics, x:Number, y:Number, points:uint, innerRadius:Number, outerRadius:Number, angle:Number = 0):void {
  227.             if (points <= 2) {
  228.                 throw ArgumentError("FastShapes.drawStar() - parameter 'points' needs to be atleast 3");
  229.                 return;
  230.             }
  231.             var step:Number, startnstep:Number, halfStep:Number, start:Number, n:Number, dx:Number, dy:Number;
  232.             step = FastShapes.PI2 / points;
  233.             halfStep = step * 0.5;
  234.             start = angle * FastShapes.TO_RAD;
  235.             target.moveTo(x + (testCos(start) * outerRadius), y - (testSin(start) * outerRadius));
  236.             for (n = 1; n <= points; ++n) {
  237.                 startnstep = start + (step * n);
  238.                 dx = x + testCos(startnstep - halfStep) * innerRadius;
  239.                 dy = y - testSin(startnstep - halfStep) * innerRadius;
  240.                 target.lineTo(dx, dy);
  241.                 dx = x + testCos(startnstep) * outerRadius;
  242.                 dy = y - testSin(startnstep) * outerRadius;
  243.                 target.lineTo(dx, dy);
  244.             }
  245.         }
  246.  
  247.         /**
  248.          * a method for creating polygon shapes.  Negative values will draw
  249.          * the polygon in reverse direction.  Negative drawing may be useful
  250.          * for creating knock-outs in masks.
  251.          */
  252.         public static function drawPolygon(target:Graphics, x:Number, y:Number, sides:uint, radius:Number, angle:Number = 0):void {
  253.             if (sides <= 2) {
  254.                 throw ArgumentError("FastShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");
  255.                 return;
  256.             }
  257.             var step:Number, startnstep:Number, start:Number, n:Number, dx:Number, dy:Number;
  258.             step = FastShapes.PI2 / sides;
  259.             start = angle * FastShapes.TO_RAD;
  260.             target.moveTo(x + (testCos(start) * radius), y - (testSin(start) * radius));
  261.             for (n = 1; n <= sides; ++n) {
  262.                 startnstep = start + (step * n);
  263.                 dx = x + testCos(startnstep) * radius;
  264.                 dy = y - testSin(startnstep) * radius;
  265.                 target.lineTo(dx, dy);
  266.             }
  267.         }
  268.  
  269.         /**
  270.          * a method for creating hand drawn polygon shapes.  Negative values will draw
  271.          * the polygon in reverse direction.  Negative drawing may be useful
  272.          * for creating knock-outs in masks.   
  273.          */
  274.         public static function handDrawPolygon(target:Graphics, x:Number, y:Number, sides:uint, radius:Number, wobbleFactor:Number = 0.05, angle:Number = 0):void {
  275.             if (sides <= 2) {
  276.                 throw ArgumentError("FastShapes.handDrawPolygon() - parameter 'sides' needs to be atleast 3");
  277.                 return;
  278.             }
  279.             var step:Number, start:Number, startnstep:Number, n:Number, dx:Number, dy:Number;
  280.             step = FastShapes.PI2 / sides;
  281.             start = angle * FastShapes.TO_RAD;
  282.             var p1:Point = new Point(x + (testCos(start) * radius), y - (testSin(start) * radius))
  283.             var p2:Point = new Point();
  284.             target.moveTo(p1.x, p1.y);
  285.             for (n = 1; n <= sides; ++n) {
  286.                 startnstep = start + (step * n);
  287.                 p2.x = x + testCos(startnstep) * radius; //dx
  288.                 p2.y = y - testSin(startnstep) * radius; //dy
  289.                 handDrawLine(target, p1, p2, wobbleFactor);
  290.                 p1.x = p2.x;
  291.                 p1.y = p2.y;
  292.             }
  293.         }
  294.  
  295.         /**
  296.          * Burst is a method for drawing star bursts.  If you've ever worked
  297.          * with an advertising department, you know what they are ;-)
  298.          * Clients tend to want them, Developers tend to hate them...      
  299.          */
  300.         public static function drawBurst(target:Graphics, x:Number, y:Number, sides:uint, innerRadius:Number, outerRadius:Number, angle:Number = 0):void {
  301.             if (sides <= 2) {
  302.                 throw ArgumentError("FastShapes.drawBurst - parameter 'sides' needs to be atleast 3");
  303.                 return;
  304.             }
  305.             var step:Number, halfStep:Number, qtrStep:Number, qtrStep3:Number, start:Number, n:Number, dx:Number, dy:Number, cx:Number, cy:Number;
  306.             var startnstep:Number, innercos:Number;
  307.             step = FastShapes.PI2 / sides;
  308.             qtrStep = step * 0.25;
  309.             halfStep = step * 0.5;
  310.             qtrStep3 = step * 0.75;
  311.             start = angle * FastShapes.TO_RAD;
  312.             target.moveTo(x + (testCos(start) * outerRadius), y - (testSin(start) * outerRadius));
  313.             for (n = 1; n <= sides; ++n) {
  314.                 startnstep = start + (step * n);
  315.                 innercos = (innerRadius / testCos(qtrStep));
  316.                 cx = x + testCos(startnstep - qtrStep3) * innercos;
  317.                 cy = y - testSin(startnstep - qtrStep3) * innercos;
  318.                 dx = x + testCos(startnstep - halfStep) * innerRadius;
  319.                 dy = y - testSin(startnstep - halfStep) * innerRadius;
  320.                 target.curveTo(cx, cy, dx, dy);
  321.                 cx = x + testCos(startnstep - qtrStep) * innercos;
  322.                 cy = y - testSin(startnstep - qtrStep) * innercos;
  323.                 dx = x + testCos(startnstep) * outerRadius;
  324.                 dy = y - testSin(startnstep) * outerRadius;
  325.                 target.curveTo(cx, cy, dx, dy);
  326.             }
  327.         }
  328.          
  329.         // draws a gear shape on the Graphics target             
  330.         public static function drawGear(target:Graphics, x:Number, y:Number, sides:uint, innerRadius:Number = 80, outerRadius:Number = 4, angle:Number = 0, holeSides:Number = 2, holeRadius:Number = 0):void {
  331.             if (sides <= 2) {
  332.                 throw ArgumentError("FastShapes.drawGear() - parameter 'sides' needs to be atleast 3");
  333.                 return;
  334.             }
  335.             var step:Number, startnstep:Number, qtrStep:Number, qtrStep2:Number, qtrStep3:Number, start:Number, n:Number, dx:Number, dy:Number;
  336.             step = FastShapes.PI2 / sides;
  337.             qtrStep = step * 0.25;
  338.             qtrStep2 = (qtrStep * 2);
  339.             qtrStep3 = (qtrStep * 3);
  340.             start = angle * FastShapes.TO_RAD;
  341.             target.moveTo(x + (testCos(start) * outerRadius), y - (testSin(start) * outerRadius));
  342.             for (n = 1; n <= sides; ++n) {
  343.                 startnstep = start + (step * n);
  344.                 dx = x + testCos(startnstep - qtrStep3) * innerRadius;
  345.                 dy = y - testSin(startnstep - qtrStep3) * innerRadius;
  346.                 target.lineTo(dx, dy);
  347.                 dx = x + testCos(startnstep - qtrStep2) * innerRadius;
  348.                 dy = y - testSin(startnstep - qtrStep2) * innerRadius;
  349.                 target.lineTo(dx, dy);
  350.                 dx = x + testCos(startnstep - qtrStep) * outerRadius;
  351.                 dy = y - testSin(startnstep - qtrStep) * outerRadius;
  352.                 target.lineTo(dx, dy);
  353.                 dx = x + testCos(startnstep) * outerRadius;
  354.                 dy = y - testSin(startnstep) * outerRadius;
  355.                 target.lineTo(dx, dy);
  356.             }
  357.             // This is complete overkill... but I had it done already. :)
  358.             if (holeSides > 2) {
  359.                 step = FastShapes.PI2 / holeSides;
  360.                 target.moveTo(x + (testCos(start) * holeRadius), y - (testSin(start) * holeRadius));
  361.                 for (n = 1; n <= holeSides; ++n) {
  362.                     startnstep = start + (step * n);
  363.                     dx = x + testCos(startnstep) * holeRadius;
  364.                     dy = y - testSin(startnstep) * holeRadius;
  365.                     target.lineTo(dx, dy);
  366.                 }
  367.             }
  368.         }
  369.  
  370.         //  draws a line between two points. Make it horizontal or vertical
  371.         public static function drawLine(target:Graphics, x:Number, y:Number, length:Number, direction:String = FastShapes.HORIZONTAL_LINE):void {
  372.             switch (direction) {
  373.             case FastShapes.HORIZONTAL_LINE:
  374.                 target.moveTo(x, y);
  375.                 target.lineTo(length, y);
  376.                 break;
  377.             case FastShapes.VERTICAL_LINE:
  378.                 target.moveTo(x, y);
  379.                 target.lineTo(x, length);
  380.                 break;
  381.             }
  382.         }
  383.     }
  384. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×