Forked from: hycro's IK Test diff:1 forked from: IK Test skyfe79 forked:0favorite:0lines:99license : MIT License modified : 2012-04-03 14:21:46 Embed Tweet // forked from hycro's IK Test package { import flash.display.StageScaleMode; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; [SWF(frameRate="60")] public class IKTest extends Sprite { private var _list:SegmentList; public function IKTest() { init(); } private function init():void { stage.scaleMode = StageScaleMode.NO_SCALE; _list = createSegmentList(1000, 3); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function createSegmentList(size:uint, segmentLength:Number):SegmentList { var sl:SegmentList = new SegmentList(new Point(0, 0)); for (var i:uint = 1; i <= size; i++) { sl.addSegment(new Point(i % 2 ? segmentLength : 0, 0)); } return sl; } private const colors:Array = [0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF]; private function onEnterFrame(evt:Event):void { var count:uint = 0; _list.drag(new Point(mouseX, mouseY)); graphics.clear(); graphics.moveTo(_list.head.point0.x, _list.head.point0.y); for (var segment:Segment = _list.head; segment != null; segment = segment.next) { graphics.lineStyle(4, colors[count++ % colors.length]); graphics.lineTo(segment.point1.x, segment.point1.y); } } } } import flash.geom.Point; class SegmentList { private var _head:Segment; private var _tail:Segment; private var _origin:Point; public function SegmentList(origin:Point) { _origin = origin; } public function get tail():Segment { return _tail; } public function get head():Segment { return _head; } public function addSegment(point:Point):Segment { if (_tail) { var segment:Segment = new Segment(_tail.point1, point); segment.prev = _tail; _tail.next = segment; _tail = segment; } else { _tail = new Segment(_origin, point); _head = _tail; } return _tail; } public function drag(target:Point):void { if (_tail == null) { return; } _tail.point1 = target; for (var segment:Segment = _tail; segment != null; segment = segment.prev) { segment.restore(); } } } class Segment { public var point0:Point; public var point1:Point; public var next:Segment; public var prev:Segment; public var restoreRaito:Number = 1; private var _originalLength:Number; public function Segment(point0:Point, point1:Point) { this.point0 = point0; this.point1 = point1; _originalLength = this.length; } public function restore():void { var dx:Number = point1.x - point0.x; var dy:Number = point1.y - point0.y; var m:Number = .5 - _originalLength / Point.distance(point0, point1) * .5; point0.x += m * dx * restoreRaito * 2; point0.y += m * dy * restoreRaito * 2; point1.x -= m * dx * (1-restoreRaito) * 2; point1.y -= m * dy * (1-restoreRaito) * 2; } public function get length():Number { return Point.distance(point0, point1); } } Code Fullscreen Preview Fullscreen