148 lines
5.0 KiB
ActionScript
Executable File
148 lines
5.0 KiB
ActionScript
Executable File
/*
|
|
Copyright (c) 2009 Yahoo! Inc. All rights reserved.
|
|
The copyrights embodied in the content of this file are licensed under the BSD (revised) open source license
|
|
*/
|
|
package com.yahoo.astra.utils
|
|
{
|
|
import flash.display.Graphics;
|
|
import flash.geom.Point;
|
|
|
|
/**
|
|
* Utility functions for drawing to <code>Graphics</code> objects.
|
|
*
|
|
* @author Josh Tynjala
|
|
* @see flash.display.Graphics
|
|
*/
|
|
public class GraphicsUtil
|
|
{
|
|
/**
|
|
* @private
|
|
* Draws a wedge.
|
|
*
|
|
* @param x x component of the wedge's center point
|
|
* @param y y component of the wedge's center point
|
|
* @param startAngle starting angle in degrees
|
|
* @param arc sweep of the wedge. Negative values draw clockwise.
|
|
* @param radius radius of wedge. If [optional] yRadius is defined, then radius is the x radius.
|
|
* @param yRadius [optional] y radius for wedge.
|
|
*/
|
|
public static function drawWedge(target:Graphics, x:Number, y:Number, startAngle:Number, arc:Number, radius:Number, yRadius:Number = NaN):void
|
|
{
|
|
// move to x,y position
|
|
target.moveTo(x, y);
|
|
|
|
// if yRadius is undefined, yRadius = radius
|
|
if(isNaN(yRadius))
|
|
{
|
|
yRadius = radius;
|
|
}
|
|
|
|
// 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.
|
|
var segs:int = Math.ceil(Math.abs(arc) / 45);
|
|
|
|
// Now calculate the sweep of each segment.
|
|
var segAngle:Number = arc / segs;
|
|
|
|
// The math requires radians rather than degrees. To convert from degrees
|
|
// use the formula (degrees/180)*Math.PI to get radians.
|
|
var theta:Number = -(segAngle / 180) * Math.PI;
|
|
|
|
// convert angle startAngle to radians
|
|
var angle:Number = -(startAngle / 180) * Math.PI;
|
|
|
|
// draw the curve in segments no larger than 45 degrees.
|
|
if(segs > 0)
|
|
{
|
|
// draw a line from the center to the start of the curve
|
|
var ax:Number = x + Math.cos(startAngle / 180 * Math.PI) * radius;
|
|
var ay:Number = y + Math.sin(-startAngle / 180 * Math.PI) * yRadius;
|
|
target.lineTo(ax, ay);
|
|
|
|
// Loop for drawing curve segments
|
|
for(var i:int = 0; i < segs; i++)
|
|
{
|
|
angle += theta;
|
|
var angleMid:Number = angle - (theta / 2);
|
|
var bx:Number = x + Math.cos(angle) * radius;
|
|
var by:Number = y + Math.sin(angle) * yRadius;
|
|
var cx:Number = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
|
|
var cy:Number = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
|
|
target.curveTo(cx, cy, bx, by);
|
|
}
|
|
// close the wedge by drawing a line to the center
|
|
target.lineTo(x, y);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draws a dashed line between two points.
|
|
*
|
|
* @param xStart The x position of the start of the line
|
|
* @param yStart The y position of the start of the line
|
|
* @param xEnd The x position of the end of the line
|
|
* @param yEnd The y position of the end of the line
|
|
* @param dashSize the size of dashes, in pixels
|
|
* @param gapSize the size of gaps between dashes, in pixels
|
|
*/
|
|
public static function drawDashedLine(target:Graphics, xStart:Number, yStart:Number, xEnd:Number, yEnd:Number, dashSize:Number = 10, gapSize:Number = 10):void
|
|
{
|
|
// calculate the length of a segment
|
|
var segmentLength:Number = dashSize + gapSize;
|
|
|
|
// calculate the length of the dashed line
|
|
var xDelta:Number = xEnd - xStart;
|
|
var yDelta:Number = yEnd - yStart;
|
|
var delta:Number = Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2));
|
|
|
|
// calculate the number of segments needed
|
|
var segmentCount:int = Math.floor(Math.abs(delta / segmentLength));
|
|
|
|
// get the angle of the line in radians
|
|
var radians:Number = Math.atan2(yDelta, xDelta);
|
|
|
|
// start the line here
|
|
var xCurrent:Number = xStart;
|
|
var yCurrent:Number = yStart;
|
|
|
|
// add these to cx, cy to get next seg start
|
|
xDelta = Math.cos(radians) * segmentLength;
|
|
yDelta = Math.sin(radians) * segmentLength;
|
|
|
|
// loop through each segment
|
|
for(var i:int = 0; i < segmentCount; i++)
|
|
{
|
|
target.moveTo(xCurrent, yCurrent);
|
|
target.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
|
|
xCurrent += xDelta;
|
|
yCurrent += yDelta;
|
|
}
|
|
|
|
// handle last segment as it is likely to be partial
|
|
target.moveTo(xCurrent, yCurrent);
|
|
delta = Math.sqrt((xEnd - xCurrent) * (xEnd - xCurrent) + (yEnd - yCurrent) * (yEnd - yCurrent));
|
|
|
|
if(delta > dashSize)
|
|
{
|
|
// segment ends in the gap, so draw a full dash
|
|
target.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
|
|
}
|
|
else if(delta > 0)
|
|
{
|
|
// segment is shorter than dash so only draw what is needed
|
|
target.lineTo(xCurrent + Math.cos(radians) * delta, yCurrent + Math.sin(radians) * delta);
|
|
}
|
|
|
|
// move the pen to the end position
|
|
target.moveTo(xEnd, yEnd);
|
|
}
|
|
|
|
}
|
|
} |