/**
* Copyright k__ ( http://wonderfl.net/user/k__ )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2o4H
*/
package {
import flash.display.*;
import flash.events.*;
import flash.geom.Rectangle;
public class Main extends Sprite {
private var circles:Vector.<VerletFlexCircle>;
public function Main() {
var rect:Rectangle = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
circles = new Vector.<VerletFlexCircle>;
circles.push(new VerletFlexCircle(stage.stageWidth / 2, stage.stageHeight / 2, 20 ,60, rect));
circles.push(new VerletFlexCircle(stage.stageWidth / 2, stage.stageHeight / 3, 20 ,100, rect));
circles[0].vx= 8;
circles[1].vx= 8;
circles[0].vy= 3;
circles[1].vy= 16;
addEventListener(Event.ENTER_FRAME, h_enterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, h_mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, h_mouseUp);
}
private function h_enterFrame(evt:Event):void {
var i:uint;
for (i = 0; i < circles.length; i ++) {
circles[i].update();
}
graphics.clear();
for (i = 0; i < circles.length; i ++) {
circles[i].render(graphics);
}
}
private function h_mouseDown(evt:MouseEvent):void {
}
private function h_mouseUp(evt:MouseEvent):void {
}
}
}
import flash.display.Graphics;
import flash.geom.Rectangle;
class Super extends Array {}
class Super2 extends Super {}
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();
}
public function highlight(g:Graphics):void {
g.beginFill(0xFF66FF, 0.5);
g.drawCircle(x, y, 5);
g.endFill();
}
}
class VerletStick extends Super {
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);
}
}
class VerletFlexCircle extends Super2 {
private var _cx:Number,_cy:Number, _radius:Number;
private var points:Vector.<VerletPoint>, sticks:Vector.<VerletStick>;
private var _rect:Rectangle;
public function VerletFlexCircle(x:Number, y:Number, len:Number,radius:Number, rect:Rectangle) {
points=new Vector.<VerletPoint>;
sticks=new Vector.<VerletStick>;
for (var i:uint = 0; i < len; i ++) {
var theta:Number = Math.PI * 2 / len * i;
points.push(new VerletPoint(Math.cos(theta) * radius + x, Math.sin(theta) * radius + y));
}
for (i = 0; i < len; i ++) {
sticks.push(new VerletStick(points[i], points[(i + 1) % len]));
sticks.push(new VerletStick(points[i], points[(i + 8) % len]));
}
_rect = rect;
_radius = radius;
}
public function update():void {
var i:uint,xsum:Number = 0, ysum:Number = 0;
for (i = 0; i < points.length; i ++) {
points[i].update();
}
for (i = 0; i < points.length; i ++) {
points[i].constrain(_rect);
}
for (i = 0; i < sticks.length; i ++) {
sticks[i].update();
}
for (i = 0; i < points.length; i ++) {
xsum += points[i].x;
ysum += points[i].y;
}
_cx = xsum / points.length;
_cy = ysum / points.length;
}
public function render(g:Graphics):void {
g.beginFill(0xFF0000, 0.5);
g.drawCircle(cx, cy, 5);
g.endFill();
var i:uint;
for (i = 0; i < points.length; i ++) {
points[i].render(g);
}
for (i = 0; i < sticks.length; i ++) {
sticks[i].render(g);
}
}
public function get cx():Number {
return _cx;
}
public function get cy():Number {
return _cy;
}
public function get radius():Number {
return _radius;
}
public function set vx(n:Number):void {
for (var i:uint = 0; i < points.length; i ++) {
points[i].vx = n;
}
}
public function set vy(n:Number):void {
for (var i:uint = 0; i < points.length; i ++) {
points[i].vy = n;
}
}
}