Index: lams_flex/LamsFlexCommon/.flexLibProperties =================================================================== diff -u -r288a24d430e10138d07e89241364fc014a1f9352 -r407ed0318f79527ec2ae2220411380d708d6d9e6 --- lams_flex/LamsFlexCommon/.flexLibProperties (.../.flexLibProperties) (revision 288a24d430e10138d07e89241364fc014a1f9352) +++ lams_flex/LamsFlexCommon/.flexLibProperties (.../.flexLibProperties) (revision 407ed0318f79527ec2ae2220411380d708d6d9e6) @@ -1,55 +1,58 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - + + + - - - - + + + + - + @@ -61,32 +64,32 @@ + - - - + - + + - - + + - - - + + + @@ -134,34 +137,34 @@ - + - - + + - + - - - + + + - + @@ -176,33 +179,33 @@ - + - - + - + + - - + + - + - + @@ -216,17 +219,17 @@ - + - + - + @@ -427,53 +430,53 @@ - + - + - + - + - + - + - - + + - - + + - + - + - - + + @@ -482,8 +485,8 @@ - + @@ -494,88 +497,88 @@ - + - - + + - + - + - + - + - - + + - - - - + + + + - - + + - - + + - - + + - - + + @@ -584,26 +587,26 @@ - - + + - - + + - + - + @@ -612,42 +615,42 @@ - + - - + + - + - + - - + + - + - + @@ -657,39 +660,39 @@ - + - + - - - + + + - + - + - - + + - + @@ -706,8 +709,8 @@ - + @@ -718,88 +721,88 @@ - + - - + + - - + + - + - + - + - + - + - + - + - - + - - + + + - - - + + + - + - + - + Index: lams_flex/LamsFlexCommon/src/com/dncompute/geom/GeomUtil.as =================================================================== diff -u --- lams_flex/LamsFlexCommon/src/com/dncompute/geom/GeomUtil.as (revision 0) +++ lams_flex/LamsFlexCommon/src/com/dncompute/geom/GeomUtil.as (revision 407ed0318f79527ec2ae2220411380d708d6d9e6) @@ -0,0 +1,133 @@ +package com.dncompute.geom { + + import flash.geom.Point; + + + /** + * + * Copyright (c) 2008 Noel Billig (www.dncompute.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + /** + * + * The line segment intersection code used here is based off of Erik Gustavsson's + * tutorial found here: http://www.zikko.se/resources/lineIntersection.php + * That page reads: "All content on these pages may be used, copied and modifed freely." + * + */ + public class GeomUtil { + + /** + * + * Returns the point of intersection between the line connecting point a1 to a2 + * and the line connecting point b1 to b2. + * + */ + public static function getLineSegmentIntersection( + a1:Point,a2:Point, + b1:Point,b2:Point + ):Point { + + //XXX: Add an optimization here to see if the bounding boxes even overlap + + //Figure out where the lines intersect + var intersection:Point = getLineIntersection(a1,a2,b1,b2); + + //They could be parellel, in which case there is no line intersection + if (intersection == null) return null; + + //If the lines intersect, check and see if the intersection falls on the segments + if (inRange(intersection,a1,a2) && inRange(intersection,b1,b2)) { + return intersection; + } + + return null; + + } + + + /** + * + * Calculate the intersection between two lines. The intersection point + * may not necesarily occur on either line segment. To only get the line + * segment intersection, use getLineSegmentIntersection instead + * + */ + public static function getLineIntersection ( + a1:Point,a2:Point, + b1:Point,b2:Point + ):Point { + + //calculate directional constants + var k1:Number = (a2.y-a1.y) / (a2.x-a1.x); + var k2:Number = (b2.y-b1.y) / (b2.x-b1.x); + + // if the directional constants are equal, the lines are parallel, + // meaning there is no intersection point. + if( k1 == k2 ) return null; + + var x:Number,y:Number; + var m1:Number,m2:Number; + + // an infinite directional constant means the line is vertical + if( !isFinite(k1) ) { + + // so the intersection must be at the x coordinate of the line + x = a1.x; + m2 = b1.y - k2 * b1.x; + y = k2 * x + m2; + + // same as above for line 2 + } else if ( !isFinite(k2) ) { + + m1 = a1.y - k1 * a1.x; + x = b1.x; + y = k1 * x + m1; + + // if neither of the lines are vertical + } else { + + m1 = a1.y - k1 * a1.x; + m2 = b1.y - k2 * b1.x; + x = (m1-m2) / (k2-k1); + y = k1 * x + m1; + + } + + return new Point(x,y); + } + + + private static function inRange(pnt:Point,a:Point,b:Point):Boolean { + + if (a.x != b.x) { + return pnt.x <= a.x != pnt.x < b.x; + } else { + return pnt.y <= a.y != pnt.y < b.y; + } + + } + + + } + +} \ No newline at end of file Index: lams_flex/LamsFlexCommon/src/com/dncompute/graphics/ArrowStyle.as =================================================================== diff -u --- lams_flex/LamsFlexCommon/src/com/dncompute/graphics/ArrowStyle.as (revision 0) +++ lams_flex/LamsFlexCommon/src/com/dncompute/graphics/ArrowStyle.as (revision 407ed0318f79527ec2ae2220411380d708d6d9e6) @@ -0,0 +1,81 @@ +package com.dncompute.graphics { + + /** + * + * Copyright (c) 2008 Noel Billig (www.dncompute.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + /* + * @param width - if width is -1, the arrow is equilateral + * @param shaftPosition - Determines how far along the arrow + * shaft the head is connected. -1 will result in a + * diamond shape, 0 will be a standard triangle, .5 will + * be a recessed arrow (like a mouse pointer). Anything + * greater than 1 will invert the shape. + * @param shaftControlPosition - let's you curve the line where + * the base points meet the shaft. Determines what percentage + * from the shaft-head to base points to place the control points + * @param shaftControlSize - Less than .5 sharpens the + * shape, whereas anything greater than .5 makes it bulbous + */ + public class ArrowStyle { + + public var headWidth:Number=-1; //Relative width of arrow head + + /** + * + * Not used in drawArrowHead because the length is + * determined by the points passed in + * + */ + public var headLength:Number=10; //Pixel Length of arrow head + + + public var shaftThickness:Number=2; + public var shaftPosition:Number=0; + + /** + * Not used in drawArrow, only drawArrowHead + * This let's you curve the line at the base of the arrow + */ + public var shaftControlPosition:Number=.5; + /** + * Not used in drawArrow, only drawArrowHead + * This let's you curve the line at the base of the arrow + */ + public var shaftControlSize:Number=.5; + + + public var edgeControlPosition:Number=.5; + public var edgeControlSize:Number=.5; + + public function ArrowStyle(presets:Object=null) { + if (presets != null) { + for (var name:String in presets) { + this[name] = presets[name]; + } + } + } + + } + +} \ No newline at end of file Index: lams_flex/LamsFlexCommon/src/com/dncompute/graphics/GraphicsUtil.as =================================================================== diff -u --- lams_flex/LamsFlexCommon/src/com/dncompute/graphics/GraphicsUtil.as (revision 0) +++ lams_flex/LamsFlexCommon/src/com/dncompute/graphics/GraphicsUtil.as (revision 407ed0318f79527ec2ae2220411380d708d6d9e6) @@ -0,0 +1,158 @@ +package com.dncompute.graphics { + + import com.dncompute.geom.GeomUtil; + + import flash.display.Graphics; + import flash.geom.Point; + + /** + * + * Copyright (c) 2008 Noel Billig (www.dncompute.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + + public class GraphicsUtil { + + public static function drawArrow(graphics:Graphics, + start:Point,end:Point, + style:Object=null):void { + + if (start.equals(end)) return; + + var arrowStyle:ArrowStyle; + if (style == null) { + arrowStyle = new ArrowStyle(); + } else if (style is ArrowStyle) { + arrowStyle = style as ArrowStyle; + } else { + arrowStyle = new ArrowStyle(style); + } + + var fullVect:Point = end.subtract(start); + var halfWidth:Number = (arrowStyle.headWidth != -1) ? arrowStyle.headWidth/2 : arrowStyle.headLength/2; + + //Figure out the line start/end points + var startNorm:Point = new Point(fullVect.y,-fullVect.x); + startNorm.normalize(arrowStyle.shaftThickness/2); + var start1:Point = start.add(startNorm); + var start2:Point = start.subtract(startNorm); + var end1:Point = end.add(startNorm); + var end2:Point = end.subtract(startNorm); + + //figure out where the arrow head starts + var headPnt:Point = fullVect.clone(); + headPnt.normalize(headPnt.length-arrowStyle.headLength); + headPnt = headPnt.add(start); + + //calculate the arrowhead corners + var headPntNorm:Point = startNorm.clone(); + headPntNorm.normalize(halfWidth); + var edge1:Point = headPnt.add(headPntNorm); + var edge2:Point = headPnt.subtract(headPntNorm); + + //Figure out where the arrow connects the the shaft, then calc the intersections + var shaftCenter:Point = Point.interpolate(end,headPnt,arrowStyle.shaftPosition); + var inter1:Point = GeomUtil.getLineIntersection(start1,end1,shaftCenter,edge1); + var inter2:Point = GeomUtil.getLineIntersection(start2,end2,shaftCenter,edge2); + + //Figure out the control points + var edgeCenter:Point = Point.interpolate(end,headPnt,arrowStyle.edgeControlPosition); + var edgeNorm:Point = startNorm.clone(); + edgeNorm.normalize(halfWidth*arrowStyle.edgeControlSize); + var edgeCntrl1:Point = edgeCenter.add(edgeNorm); + var edgeCntrl2:Point = edgeCenter.subtract(edgeNorm); + + + graphics.moveTo(start1.x,start1.y); + graphics.lineTo(inter1.x,inter1.y); + graphics.lineTo(edge1.x,edge1.y); + graphics.curveTo(edgeCntrl1.x,edgeCntrl1.y,end.x,end.y); + graphics.curveTo(edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y); + graphics.lineTo(inter2.x,inter2.y); + graphics.lineTo(start2.x,start2.y); + graphics.lineTo(start1.x,start1.y); + } + + public static function drawArrowHalfway(graphics:Graphics, + start:Point,end:Point, + style:Object=null):void { + + + var endOrig:Point = end.clone(); + end = Point.interpolate(start, end, 0.4); + + if (start.equals(end)) return; + + var arrowStyle:ArrowStyle; + if (style == null) { + arrowStyle = new ArrowStyle(); + } else if (style is ArrowStyle) { + arrowStyle = style as ArrowStyle; + } else { + arrowStyle = new ArrowStyle(style); + } + + var fullVect:Point = end.subtract(start); + var halfWidth:Number = (arrowStyle.headWidth != -1) ? arrowStyle.headWidth/2 : arrowStyle.headLength/2; + + //Figure out the line start/end points + var startNorm:Point = new Point(fullVect.y,-fullVect.x); + startNorm.normalize(arrowStyle.shaftThickness/2); + var start1:Point = start.add(startNorm); + var start2:Point = start.subtract(startNorm); + var end1:Point = end.add(startNorm); + var end2:Point = end.subtract(startNorm); + + //figure out where the arrow head starts + var headPnt:Point = fullVect.clone(); + headPnt.normalize(headPnt.length-arrowStyle.headLength); + headPnt = headPnt.add(start); + + //calculate the arrowhead corners + var headPntNorm:Point = startNorm.clone(); + headPntNorm.normalize(halfWidth); + var edge1:Point = headPnt.add(headPntNorm); + var edge2:Point = headPnt.subtract(headPntNorm); + + //Figure out where the arrow connects the the shaft, then calc the intersections + var shaftCenter:Point = Point.interpolate(end,headPnt,arrowStyle.shaftPosition); + var inter1:Point = GeomUtil.getLineIntersection(start1,end1,shaftCenter,edge1); + var inter2:Point = GeomUtil.getLineIntersection(start2,end2,shaftCenter,edge2); + + //Figure out the control points + var edgeCenter:Point = Point.interpolate(end,headPnt,arrowStyle.edgeControlPosition); + var edgeNorm:Point = startNorm.clone(); + edgeNorm.normalize(halfWidth*arrowStyle.edgeControlSize); + var edgeCntrl1:Point = edgeCenter.add(edgeNorm); + var edgeCntrl2:Point = edgeCenter.subtract(edgeNorm); + + + graphics.moveTo(start1.x,start1.y); + graphics.lineTo(inter1.x,inter1.y); + graphics.lineTo(edge1.x,edge1.y); + graphics.curveTo(edgeCntrl1.x,edgeCntrl1.y,end.x,end.y); + graphics.curveTo(edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y); + graphics.lineTo(inter2.x,inter2.y); + + } + } + +} \ No newline at end of file