package creatures.parts { import flash.display.Graphics; import flash.geom.Matrix; import flash.geom.Point; public class Segment { private var base:Matrix = new Matrix(); private var transformMatrix:Matrix = new Matrix(); private var _size:Number; private var _rotation:Number = 0; private var _children:Array = new Array(); private var owner:Segment; private var _style:Object = new Object(); private static var styles:Object = { borderThickness:null, borderColor:0, backgroundColor:0xFFFFFF }; private static var newStyle:Object = styles; public function get size():Number { return _size; } public function set size(n:Number):void { _size = n; } public function get x():Number { return base.tx; } public function set x(n:Number):void { base.tx = n; } public function get y():Number { return base.ty; } public function set y(n:Number):void { base.ty = n; } public function get rotation():Number { return _rotation; } public function set rotation(n:Number):void { _rotation = n; } public function get location():Point { return new Point(transformMatrix.tx, transformMatrix.ty); } public function get children():Array { return _children; } public function Segment(x:Number = 0, y:Number = 0, size:Number = 25) { base.tx = x; base.ty = y; _size = size; setStyle(newStyle); transform(); } public function clone():Segment { var segment:Segment = new Segment(); segment._size = _size; segment._rotation = _rotation; segment.base = base.clone(); segment.transformMatrix = transformMatrix.clone(); segment.setStyle(_style); return segment; } public function toString():String { return "[Segment]"; } public function addChild(child:Segment):void { child.owner = this; _children.unshift(child); } public static function setNewStyle(style:Object):void { newStyle = new Object(); for (var prop:String in styles) { if (prop in style) { newStyle[prop] = style[prop]; } } } public function setStyle(style:Object):void { for (var prop:String in styles) { if (prop in style) { _style[prop] = style[prop]; } } } public function transform(parentTransform:Matrix = null):void { // transform segment transformMatrix = base.clone(); transformMatrix.rotate(_rotation); if (parentTransform) { transformMatrix.concat(parentTransform); } // transform children var child:Segment; for each(child in _children) { child.transform(transformMatrix); } } public function drawIn(target:Graphics, deep:Boolean = true):void { // draw children if (deep) { var child:Segment; for each(child in _children) { child.drawIn(target); } } // style var hasLine:Boolean = !isNaN(_style.borderThickness) && _style.borderThickness != null && !isNaN(_style.borderColor) && _style.borderColor != null; var hasFill:Boolean = !isNaN(_style.backgroundColor) && _style.backgroundColor != null; if (hasLine) { target.lineStyle(_style.borderThickness, _style.borderColor); } if (hasFill) { target.beginFill(_style.backgroundColor); } if (hasLine || hasFill) { var loc:Point = location; // draw limb to owner if (owner) { var ownerSize:Number = owner.size; var ownerLoc:Point = owner.location; var length:Number = Point.distance(loc, ownerLoc); var s:Number = Math.min(_size, ownerSize); if (length > s) { var baseAngle:Number = Math.atan2(loc.y - ownerLoc.y, loc.x - ownerLoc.x); var b:Number = Math.max(_size, ownerSize); var angleOffset:Number = (b == s) ? Math.PI/2 : (Math.PI/2) - Math.asin(b/(length * b/(b-s))); var angle1:Number = baseAngle + angleOffset; var cosA1:Number = Math.cos(angle1); var sinA1:Number = Math.sin(angle1); var angle2:Number = baseAngle - angleOffset; var cosA2:Number = Math.cos(angle2); var sinA2:Number = Math.sin(angle2); var initx:Number = ownerLoc.x + cosA1*ownerSize; var inity:Number = ownerLoc.y + sinA1*ownerSize; target.moveTo(initx, inity); target.lineTo(loc.x + cosA1*_size, loc.y + sinA1*_size); target.lineTo(loc.x + cosA2*_size, loc.y + sinA2*_size); target.lineTo(ownerLoc.x + cosA2*ownerSize, ownerLoc.y + sinA2*ownerSize); target.lineTo(initx, inity); target.endFill(); } } // draw segment if (hasLine) { target.lineStyle(_style.borderThickness, _style.borderColor); } if (hasFill) { target.beginFill(_style.backgroundColor); } target.drawCircle(loc.x, loc.y, _size); target.endFill(); } } } }