A simple demonstration of Verlet structure based on AdvancED ActionScript 3.0 Animation by Keith Peters
package {
import flash.display.*;
import flash.events.*;
import flash.geom.Rectangle;
public class Main extends Sprite{
private var points:Vector.<VerletPoint>;
private var sticks:Vector.<VerletStick>;
private var rect:Rectangle;
private var acc:uint = 1;
private var len:uint = 15;
public function Main() {
points = new Vector.<VerletPoint>;
sticks = new Vector.<VerletStick>;
rect = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
for (var i:uint = 0; i < len; i ++) {
if (i >= 1) {
points.push(new VerletPoint(Math.random() * 100 - 50 + points[i - 1].x, Math.random() * 100 - 50 + points[i - 1].y));
points[i].constrain(rect);
sticks.push(new VerletStick(points[i], points[i - 1]));
} else {
points.push(new VerletPoint(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight));
}
if (Math.random() < 0.5 && i >= 2) {
sticks.push(new VerletStick(points[i], points[Math.floor(Math.random() * (i - 2))]));
}
points[i].x += Math.random() * 7 - 4;
points[i].y += Math.random() * 7 - 4;
}
addEventListener(Event.ENTER_FRAME, h_enterFrame);
}
private function h_enterFrame(evt:Event):void {
var i:uint, j:uint;
for (i = 0; i < points.length; i ++) {
points[i].update();
}
for (i = 0; i < points.length; i ++) {
for (j = 0; j < acc; j ++) {
points[i].constrain(rect);
}
}
for (i = 0; i < sticks.length; i ++) {
for (j = 0; j < acc; j ++) {
sticks[i].update();
}
}
graphics.clear();
for (i = 0; i < points.length; i ++) {
points[i].render(graphics);
}
for (i = 0; i < sticks.length; i ++) {
sticks[i].render(graphics);
}
}
}
}package {
import flash.display.Graphics;
import flash.geom.Rectangle;
public class VerletPoint {
public var x:Number;
public var y:Number;
private var ox:Number;
private var oy:Number;
public function VerletPoint(x:Number, y:Number) {
setPos(x, y);
}
public function update():void {
var tx:Number=x;
var ty:Number=y;
x+=vx;
y+=vy;
ox=tx;
oy=ty;
}
public function setPos(x:Number, y:Number):void {
this.x = ox = x;
this.y = oy = y;
}
public function constrain(rect:Rectangle):void {
x = Math.max(rect.left, Math.min(rect.right, x));
y = Math.max(rect.top, Math.min(rect.bottom, y));
}
public function set vx(n:Number):void {
ox = x - n;
}
public function set vy(n:Number):void {
oy = y - n;
}
public function get vx():Number {
return x - ox;
}
public function get vy():Number {
return y - oy;
}
public function render(g:Graphics):void {
g.beginFill(0xFF6600, 0.5);
g.drawCircle(x, y, 3);
g.endFill();
}
}
}package {
import flash.display.Graphics;
public class VerletStick {
private var pa:VerletPoint;
private var pb:VerletPoint;
private var len:Number;
public function VerletStick(pa:VerletPoint, pb:VerletPoint, len:Number = -1) {
this.pa = pa;
this.pb = pb;
if (len == -1) {
var dx:Number = pa.x - pb.x;
var dy:Number = pa.y - pb.y;
this.len = Math.sqrt(dx * dx + dy * dy)
} else {
this.len = len;
}
}
public function update():void {
var dx:Number = pb.x - pa.x;
var dy:Number = pb.y - pa.y;
var d:Number = Math.sqrt(dx * dx + dy * dy);
var diff:Number = len - d;
var offsetX:Number = (diff * dx / d) / 2;
var offsetY:Number = (diff * dy / d) / 2;
pa.x -= offsetX;
pa.y -= offsetY;
pb.x += offsetX;
pb.y += offsetY;
}
public function render(g:Graphics):void {
g.lineStyle(0,0xFF6600,0.5);
g.moveTo(pa.x, pa.y);
g.lineTo(pb.x, pb.y);
}
}
}