package flare.util {
import flash.display.Graphics;
/**
* Utility class defining shape types and shape drawing routines. All shape
* drawing functions take two arguments: a Graphics context
* to draw with and a size parameter determining the radius of the shape
* (i.e., the height and width of the shape are twice the size parameter).
*
*
All shapes are indicated by a name. This class registers these names
* with drawing functions, allowing the lookup of shape rendering routines
* by the shapes name. For example, these shape names may be assigned using
* a flare.vis.operator.encoder.ShapeEncoder and then later
* rendered by looking up the shape with this class, as done by the
* flare.vis.data.render.ShapeRenderer class. The set of
* available shapes can be extended by using the static
* setShape method to register a new shape name and
* drawing function.
*/
public class Shapes {
/** Constant indicating a straight line shape. */
public static const LINE : String = "line";
/** Constant indicating a Bezier curve. */
public static const BEZIER : String = "bezier";
/** Constant indicating a cardinal spline. */
public static const CARDINAL : String = "cardinal";
/** Constant indicating a B-spline. */
public static const BSPLINE : String = "bspline";
/** Constant indicating a rectangular block shape. */
public static const BLOCK : String = "block";
/** Constant indicating a polygon shape. */
public static const POLYGON : String = "polygon";
/** Constant indicating a "polyblob" shape, a polygon whose
* edges are interpolated with a cardinal spline. */
public static const POLYBLOB : String = "polyblob";
/** Constant indicating a vertical bar shape. */
public static const VERTICAL_BAR : String = "verticalBar";
/** Constant indicating a horizontal bar shape. */
public static const HORIZONTAL_BAR : String = "horizontalBar";
/** Constant indicating a wedge shape. */
public static const WEDGE : String = "wedge";
/** Constant indicating a circle shape. */
public static const CIRCLE : String = "circle";
/** Constant indicating a square shape. */
public static const SQUARE : String = "square";
/** Constant indicating a cross shape. */
public static const CROSS : String = "cross";
/** Constant indicating an 'X' shape. */
public static const X : String = "x";
/** Constant indicating a diamond shape. */
public static const DIAMOND : String = "diamond";
/** Constant indicating a upward-pointing triangle shape. */
public static const TRIANGLE_UP : String = "triangleUp";
/** Constant indicating a downward-pointing triangle shape. */
public static const TRIANGLE_DOWN : String = "triangleDown";
/** Constant indicating a rightward-pointing triangle shape. */
public static const TRIANGLE_RIGHT : String = "triangleRight";
/** Constant indicating a leftward-pointing triangle shape. */
public static const TRIANGLE_LEFT : String = "triangleLeft";
private static var _shapes : Object = {
circle: drawCircle, square: drawSquare, cross: drawCross, x: drawX, diamond: drawDiamond, triangleUp: drawTriangleUp, triangleDown: drawTriangleDown, triangleRight: drawTriangleRight, triangleLeft: drawTriangleLeft
};
/**
* Gets the shape drawing function with the given name.
* @param name the name of the shape to draw
* @return a function for drawing the shape or null if the shape name
* is not found. The returned function takes two parameters:
* a graphics object and a numerical size value. The size value
* indicates the radius of the shape.
*/
public static function getShape(name : String) : Function {
return _shapes[name];
}
/**
* Sets the shape drawing function for a given shape name.
* @param name the name of the shape to draw
* @param draw a function for drawing the shape. This function must
* take two parameters: a graphics object and a numerical size value.
* The size value indicates the radius of the shape.
*/
public static function setShape(name : String, draw : Function) : void {
_shapes[name] = draw;
}
/**
* Resets all shape drawing functions to the default settings.
*/
public static function resetShapes() : void {
_shapes = {
circle: drawCircle, square: drawSquare, cross: drawCross, x: drawX, diamond: drawDiamond, triangleUp: drawTriangleUp, triangleDown: drawTriangleDown, triangleRight: drawTriangleRight, triangleLeft: drawTriangleLeft
};
}
// --------------------------------------------------------------------
/**
* Draws a circle shape.
* @param g the graphics context to draw with
* @param size the radius of the circle
*/
public static function drawCircle(g : Graphics, size : Number) : void {
g.drawCircle(0, 0, size);
}
/**
* Draws a square shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the square. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawSquare(g : Graphics, size : Number) : void {
g.drawRect(-size, -size, 2 * size, 2 * size);
}
/**
* Draws a cross shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the cross. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawCross(g : Graphics, size : Number) : void {
g.moveTo(0, -size);
g.lineTo(0, size);
g.moveTo(-size, 0);
g.lineTo(size, 0);
}
/**
* Draws an "x" shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the "x". The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawX(g : Graphics, size : Number) : void {
g.moveTo(-size, -size);
g.lineTo(size, size);
g.moveTo(size, -size);
g.lineTo(-size, size);
}
/**
* Draws a diamond shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the diamond. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawDiamond(g : Graphics, size : Number) : void {
g.moveTo(0, size);
g.lineTo(-size, 0);
g.lineTo(0, -size);
g.lineTo(size, 0);
g.lineTo(0, size);
}
/**
* Draws an upward-pointing triangle shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the triangle. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawTriangleUp(g : Graphics, size : Number) : void {
g.moveTo(-size, size);
g.lineTo(size, size);
g.lineTo(0, -size);
g.lineTo(-size, size);
}
/**
* Draws a downward-pointing triangle shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the triangle. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawTriangleDown(g : Graphics, size : Number) : void {
g.moveTo(-size, -size);
g.lineTo(size, -size);
g.lineTo(0, size);
g.lineTo(-size, -size);
}
/**
* Draws a right-pointing triangle shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the triangle. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawTriangleRight(g : Graphics, size : Number) : void {
g.moveTo(-size, -size);
g.lineTo(size, 0);
g.lineTo(-size, size);
g.lineTo(-size, -size);
}
/**
* Draws a left-pointing triangle shape.
* @param g the graphics context to draw with
* @param size the (half-)size of the triangle. The height and width of
* the shape will both be exactly twice the size parameter.
*/
public static function drawTriangleLeft(g : Graphics, size : Number) : void {
g.moveTo(size, -size);
g.lineTo(-size, 0);
g.lineTo(size, size);
g.lineTo(size, -size);
}
// --------------------------------------------------------------------
/**
* Draws an arc (a segment of a circle's circumference)
* @param g the graphics context to draw with
* @param x the center x-coordinate of the arc
* @param y the center y-coorindate of the arc
* @param radius the radius of the arc
* @param a0 the starting angle of the arc (in radians)
* @param a1 the ending angle of the arc (in radians)
*/
public static function drawArc(g : Graphics, x : Number, y : Number,
radius : Number, a0 : Number, a1 : Number) : void {
var slices : Number = (Math.abs(a1 - a0) * radius) / 4;
var a : Number, cx : Number = x, cy : Number = y;
for (var i : uint = 0;i <= slices; ++i) {
a = a0 + i * (a1 - a0) / slices;
x = cx + radius * Math.cos(a);
y = cy + -radius * Math.sin(a);
if (i == 0) {
g.moveTo(x, y);
} else {
g.lineTo(x, y);
}
}
}
/**
* Draws a wedge defined by an angular range and inner and outer radii.
* An inner radius of zero results in a pie-slice shape.
* @param g the graphics context to draw with
* @param x the center x-coordinate of the wedge
* @param y the center y-coorindate of the wedge
* @param outer the outer radius of the wedge
* @param inner the inner radius of the wedge
* @param a0 the starting angle of the wedge (in radians)
* @param a1 the ending angle of the wedge (in radians)
*/
public static function drawWedge(g : Graphics, x : Number, y : Number,
outer : Number, inner : Number, a0 : Number, a1 : Number) : void {
var a : Number = Math.abs(a1 - a0);
var slices : int = Math.max(4, int(a * outer / 6));
var cx : Number = x, cy : Number = y, x0 : Number, y0 : Number;
var circle : Boolean = (a >= 2 * Math.PI - 0.001);
if (slices <= 0) return;
// pick starting point
if (inner <= 0 && !circle) {
g.moveTo(cx, cy);
} else {
x0 = cx + outer * Math.cos(a0);
y0 = cy + -outer * Math.sin(a0);
g.moveTo(x0, y0);
}
// draw outer arc
for (var i : uint = 0;i <= slices; ++i) {
a = a0 + i * (a1 - a0) / slices;
x = cx + outer * Math.cos(a);
y = cy + -outer * Math.sin(a);
g.lineTo(x, y);
}
if (circle) {
// return to starting point
g.lineTo(x0, y0);
} else if (inner > 0) {
// draw inner arc
for (i = slices + 1;--i >= 0;) {
a = a0 + i * (a1 - a0) / slices;
x = cx + inner * Math.cos(a);
y = cy + -inner * Math.sin(a);
g.lineTo(x, y);
}
g.lineTo(x0, y0);
} else {
// return to center
g.lineTo(cx, cy);
}
}
/**
* Draws a polygon shape.
* @param g the graphics context to draw with
* @param a a flat object vector/array of x, y values defining the polygon
*/
public static function drawPolygon(g : Graphics, a : Vector.