topical media & game development
#graphic-flex-image-effects-06-Flex-DrawingPolygons.ax
#graphic-flex-image-effects-06-Flex-DrawingPolygons.ax
[swf]
[flash]
flex
package {
import flash.display.Sprite;
import flash.geom.Vector3D;
import flash.geom.Point;
[SWF(width=600, height=600, backgroundColor=0xFFFFFF)]
Demonstrates how to use Vector3D and local3DToGlobal() to render polygons in 3D space.
Also demonstrates how to calculate lighting of polygons based on orientation in relation
to virtual light source.
public class @ax-graphic-flex-image-effects-06-Flex-DrawingPolygons extends Sprite {
private static const LIGHT_DIRECTION:Vector3D = new Vector3D(0, 0, 1);
private static const FACE_COLOR:uint = 0x9900FF;
Constructor. Centers sprite and kicks off creation of polygons.
public function @ax-graphic-flex-image-effects-06-Flex-DrawingPolygons() {
x = stage.stageWidth/2;
y = stage.stageHeight/2;
createPolygons();
}
Creates three polygons using collections of Vector3D points
and calls to custom drawPolygon() method.
private function createPolygons():void {
var vectors:Vector.<Vector3D> = new Vector.<Vector3D>();
vectors.push(new Vector3D(-250, -250, 0));
vectors.push(new Vector3D(-100, -250, 0));
vectors.push(new Vector3D(-100, -100, 0));
vectors.push(new Vector3D(-250, -100, 0));
drawPolygon(vectors);
vectors = new Vector.<Vector3D>();
vectors.push(new Vector3D(-50, -75, -50));
vectors.push(new Vector3D(50, -75, 50));
vectors.push(new Vector3D(50, 75, 50));
vectors.push(new Vector3D(-50, 75, -50));
drawPolygon(vectors);
vectors = new Vector.<Vector3D>();
vectors.push(new Vector3D(100, 160, 50));
vectors.push(new Vector3D(250, 160, 50));
vectors.push(new Vector3D(250, 180, -50));
vectors.push(new Vector3D(100, 180, -50));
drawPolygon(vectors);
}
Draws a polygon based on the 3D points passed.
parameter: vectors A collection of vectors defining a single planar polygon.
private function drawPolygon(vectors:Vector.<Vector3D>):void {
// determines color based on polygon orientation in relation to light source
var color:uint = getFaceColor(vectors);
// converts 3D points to 2D coordinates on screen
var points:Vector.<Point> = getPoints2D(vectors);
// runs through all points and draws shape
graphics.beginFill(color);
graphics.moveTo(points[0].x, points[0].y);
for (var i:uint = 1; i < points.length; i++) {
graphics.lineTo(points[i].x, points[i].y);
}
// draw bak to initial point
graphics.lineTo(points[0].x, points[0].y);
graphics.endFill();
}
Converts 3D points to 2D screen coordinates.
parameter: vectors A collection of 3D vector points.
returns: A collection of the 2D coordinates needed to represent the 3D points.
private function getPoints2D(vectors:Vector.<Vector3D>):Vector.<Point> {
var points:Vector.<Point> = new Vector.<Point>;
var point:Point;
// runs through each point
for each (var vector:Vector3D in vectors) {
// convert the 3D point to a global 2D coordinate
point = local3DToGlobal(vector);
// convert back to local coordinate space and push into vector
points.push(globalToLocal(point));
}
return points;
}
Determines color based on polygon orientation in relation to light source.
parameter: vectors A collection of vectors defining a single planar polygon.
returns: The darkened color of the polygon based on its orientation.
private function getFaceColor(vectors:Vector.<Vector3D>):uint {
// find two edges of plane in order to determine normal vector
var U:Vector3D = getEdge(vectors[1], vectors[0]);
var V:Vector3D = getEdge(vectors[1], vectors[2]);
// find normal of plane using edges
var crossProduct:Vector3D = U.crossProduct(V);
// determine angle between plane's normal and light source's directional vector
var angle:Number = Vector3D.angleBetween(crossProduct, LIGHT_DIRECTION);
// angle will be between 0 and PI, so divide by PI to get between 0 and 1
var brightness:Number = angle/Math.PI;
// darken color based on its orientation
return darkenColor(FACE_COLOR, brightness);
}
Darkens the specified color by the specified percentage.
parameter: color The color to darken.
parameter: percent The percent by which to darken the color.
returns: The darkened color.
private function darkenColor(color:uint, percent:Number):uint {
// separate each color component
var red:uint = color >> 16 & 0xFF;
var green:uint = color >> 8 & 0xFF;
var blue:uint = color & 0xFF;
// reduce each component by percentage
red *= percent;
green *= percent;
blue *= percent;
return red << 16 | green << 8 | blue;
}
Returns a vector describing the edge between two points on a polygon.
parameter: v1 One vector point on the polygon.
parameter: v1 A second vector point on the polygon.
returns: A vector describing the edge between two points on a polygon.
private function getEdge(v1:Vector3D, v2:Vector3D):Vector3D {
// find distance between each coordinate
var x:Number = v1.x-v2.x;
var y:Number = v1.y-v2.y;
var z:Number = v1.z-v2.z;
return new Vector3D(x, y, z);
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.