Robot Arm
package {
import flash.display.*;
import flash.events.Event;
import flash.geom.Point;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="24")]
public class Program extends Sprite {
private var screen:Sprite;
private const NARM:int = 4;
private const LENGTH:Number = 60;
private var angles:Array;
private var arms:Array;
private var effector1:Sprite;
private var effector2:Sprite;
public function Program() {
this.screen = this;
var i:int;
var g:Graphics;
angles = new Array();
arms = new Array();
for (i = 0; i < NARM; i++) {
angles[i] = 0.0;
arms[i] = new Sprite();
g = arms[i].graphics;
g.lineStyle(1, 0);
g.drawRoundRect(-8, -8, LENGTH + 16, 16, 16);
g.drawCircle(0, 0, 3);
g.drawCircle(0, 0, 8);
screen.addChild(arms[i]);
}
effector1 = new Sprite();
effector2 = new Sprite();
g = effector1.graphics;
g.lineStyle(1, 0);
g.drawRect(-5, -5, 30, 10);
g.drawRect(20, -10, 5, 15);
g.drawCircle(0, 0, 8);
g = effector2.graphics;
g.lineStyle(1, 0);
g.drawRect(-5, -5, 30, 10);
g.drawRect(20, -5, 5, 15);
g.drawCircle(0, 0, 3);
screen.addChild(effector1);
screen.addChild(effector2);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function onEnterFrame(ev:Event):void {
draw();
}
private var ph:Number = 0;
public function draw():void {
var i:int;
var x:Number;
var y:Number;
var e:Point;
for (i = 0; i < 10; i++)
e = pursuit(0, new Point(465/2.0, 465/2.0), new Point(screen.mouseX, screen.mouseY));
x = y = 465/2.0;
for (i = 0; i < NARM; i++) {
arms[i].x = x;
arms[i].y = y;
arms[i].rotation = angles[i] / Math.PI * 180;
x += LENGTH * Math.cos(angles[i]);
y += LENGTH * Math.sin(angles[i]);
}
var dx:Number = e.x - screen.mouseX;
var dy:Number = e.y - screen.mouseY;
if (dx * dx + dy * dy < 50)
ph += 0.1;
var angle_e:Number = arms[NARM - 1].rotation;
var angle_ed:Number = 25 + 30 * Math.pow(Math.sin(ph), 2);
effector1.x = effector2.x = e.x - Math.cos(angles[NARM - 1]) * 25;
effector1.y = effector2.y = e.y - Math.sin(angles[NARM - 1]) * 25;
effector1.rotation = angle_e + angle_ed;
effector2.rotation = angle_e - angle_ed;
}
private function pursuit(bi:uint, o:Point, p:Point):Point {
var e:Point;
if (bi < NARM - 1) {
const o2:Point = new Point(
o.x + Math.cos(angles[bi]) * LENGTH,
o.y + Math.sin(angles[bi]) * LENGTH);
e = pursuit(bi + 1, o2, p);
} else {
e = new Point(
o.x + Math.cos(angles[bi]) * (LENGTH + 20),
o.y + Math.sin(angles[bi]) * (LENGTH + 20));
}
if ((e.y == o.y && e.x == o.x) || (p.y == o.y && p.x == o.x))
return e;
const anglee:Number = Math.atan2(e.y - o.y, e.x - o.x);
const anglep:Number = Math.atan2(p.y - o.y, p.x - o.x);
var angle_d:Number = (anglep - anglee);
if (angle_d > Math.PI) angle_d = angle_d - 2 * Math.PI;
else if (angle_d < -Math.PI) angle_d = angle_d + 2 * Math.PI;
if (angle_d > 0.025) angle_d = 0.025;
else if (angle_d < -0.025) angle_d = -0.025;
angles[bi] += angle_d;
return e;
}
}
}