IK Test 2
/**
* Copyright hycro ( http://wonderfl.net/user/hycro )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uFLY
*/
// forked from hycro's IK Test
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
[SWF(frameRate="60", width="465", height="465")]
public class IKTest2 extends Sprite {
private var _list:SegmentList;
public function IKTest2() {
init();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function init():void {
_list = createSegmentList(100, 2, new Point(stage.stageWidth/2, stage.stageHeight/2));
}
private function createSegmentList(size:uint, segmentLength:Number, origin:Point):SegmentList {
var sl:SegmentList = new SegmentList(origin);
for (var i:uint = 1; i <= size; i++) {
sl.addSegment(i % 2 ? new Point(segmentLength, 0).add(origin) : origin.clone());
}
return sl;
}
private function onEnterFrame(evt:Event):void {
_list.reach(new Point(mouseX, mouseY));
draw();
}
private const colors:Array = [0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF];
private function draw():void {
var count:uint = 0;
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);
}
graphics.lineStyle();
graphics.beginFill(0xFF0000);
graphics.drawCircle(mouseX, mouseY, 3);
graphics.endFill();
}
}
}
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.clone();
}
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.clone());
segment.prev = _tail;
_tail.next = segment;
_tail = segment;
} else {
_tail = new Segment(_origin.clone(), point);
_head = _tail;
}
return _tail;
}
public function drag(target:Point):void {
if (_tail == null) {
return;
}
_tail.point1 = target.clone();
for (var segment:Segment = _tail; segment != null; segment = segment.prev) {
segment.restore();
}
}
public function reach(target:Point):void {
if (_tail == null) {
return;
}
_tail.point1 = target.clone();
for (var segment:Segment = _tail; segment != null; segment = segment.prev) {
segment.restore(1);
}
_head.point0 = _origin.clone();
for (segment = _head; segment != null; segment = segment.next) {
segment.restore(0);
}
}
}
class Segment {
public var point0:Point;
public var point1:Point;
public var next:Segment;
public var prev:Segment;
private var _originalLength:Number;
public function Segment(point0:Point, point1:Point) {
this.point0 = point0;
this.point1 = point1;
_originalLength = Point.distance(point0, point1);
}
public function restore(raito:Number=1):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;
dx *= 2 * m;
dy *= 2 * m;
point0.x += dx * raito;
point0.y += dy * raito;
point1.x -= dx * (1-raito);
point1.y -= dy * (1-raito);
}
public function get length():Number {
return Point.distance(point0, point1);
}
}