forked from: forked from: Dynamic verlet collision with mc?
testing cloth-like stuff with this engine
/**
* Copyright makc3d ( http://wonderfl.net/user/makc3d )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ndYgZ
*/
// forked from makc3d's forked from: Dynamic verlet collision with mc?
// forked from bahngoura's Dynamic verlet collision with mc?
// forked from fakestar0826's Verlet Triangle
// forked from fakestar0826's Verlet Method
// testing cloth-like stuff with this engine
package {
import flash.events.Event;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.MovieClip;
public class FlashTest extends Sprite {
private var points:Vector.<VerletPoint>;
private var sticks:Vector.<VerletStick>;
public function FlashTest() {
// write as3 code here..
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var N:int = 9;
points = new Vector.<VerletPoint> (N * N, true);
for (var i:int = 0; i < N; i++)
for (var j:int = 0; j < N; j++) {
points [i + j * N] = new VerletPoint (50 + i * 365 / (N - 1), 80 + j * 365 / (N - 1));
}
points [0].setPosition (80, 50);
points [0].pinned = true;
points [N - 1].setPosition (465 - 80, 50);
points [N - 1].pinned = true;
sticks = new Vector.<VerletStick>;
for (i = 0; i < N; i++)
for (j = 0; j < N; j++) {
if (i < N - 1) sticks.push (new VerletStick (points [i + j * N], points [i + 1 + j * N]));
if (j < N - 1) sticks.push (new VerletStick (points [i + j * N], points [i + N + j * N]));
}
/* sticks.push (new VerletStick (points [1 + 0 * N], points [0 + 1 * N]));
sticks.push (new VerletStick (points [0 + 0 * N], points [1 + 1 * N]));
sticks.push (new VerletStick (points [N - 2 + 0 * N], points [N - 1 + 1 * N]));
sticks.push (new VerletStick (points [N - 1 + 0 * N], points [N - 2 + 1 * N]));
*/
/* sticks.push (new VerletStick (points [1 + (N - 3) * N], points [0 + (N - 2) * N]));
sticks.push (new VerletStick (points [1 + (N - 2) * N], points [0 + (N - 1) * N]));
sticks.push (new VerletStick (points [2 + (N - 2) * N], points [1 + (N - 1) * N]));
sticks.push (new VerletStick (points [3 + (N - 2) * N], points [2 + (N - 1) * N]));
sticks.push (new VerletStick (points [N - 4 + (N - 2) * N], points [N - 3 + (N - 1) * N]));
sticks.push (new VerletStick (points [N - 3 + (N - 2) * N], points [N - 2 + (N - 1) * N]));
sticks.push (new VerletStick (points [N - 2 + (N - 2) * N], points [N - 1 + (N - 1) * N]));
sticks.push (new VerletStick (points [N - 2 + (N - 3) * N], points [N - 1 + (N - 2) * N]));
*/
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
for each (var point:VerletPoint in points) {
point.y += 0.5; point.update ();
}
//繰り返しを増やすと剛体に近づく。stickのupdateメソッドにより、点同士の斥力?が働くため
for(var i:int = 0;i < 15;i++)
{
for each (var stick:VerletStick in sticks) {
stick.update ();
}
}
graphics.clear();
for each (point in points) {
point.render (graphics);
}
for each (stick in sticks) {
stick.render (graphics);
}
}
}
}
import flash.display.MovieClip;
import flash.display.Graphics;
import flash.geom.Rectangle;
class VerletPoint
{
public var x:Number;
public var y:Number;
private var _oldX:Number;
private var _oldY:Number;
public var pinned:Boolean;
public function VerletPoint(x:Number, y:Number)
{
setPosition(x, y);
}
public function update():void
{
if (pinned) {
x = _oldX;
y = _oldY;
return;
}
var tempX:Number = x;
var tempY:Number = y;
x += vx;
y += vy;
_oldX = tempX;
_oldY = tempY;
}
public function setPosition(x:Number, y:Number):void
{
this.x = _oldX = x;
this.y = _oldY = y;
}
public function set vx(value:Number):void
{
_oldX = x - value;
}
public function get vx():Number
{
return x - _oldX;
}
public function set vy(value:Number):void
{
_oldY = y - value;
}
public function get vy():Number
{
return y - _oldY;
}
public function render(g:Graphics):void
{
if (pinned) {
g.beginFill(0);
g.drawCircle(x, y, 4);
g.endFill();
}
}
}
class VerletStick
{
private var _pointA:VerletPoint;
private var _pointB:VerletPoint;
private var _length:Number;
public function VerletStick(pointA:VerletPoint, pointB:VerletPoint, length:Number = -1)
{
_pointA = pointA;
_pointB = pointB;
if(length == -1)
{
var dx:Number = _pointA.x - _pointB.x;
var dy:Number = _pointA.y - _pointB.y;
_length = Math.sqrt(dx * dx + dy * dy);
}
else
{
_length = length;
}
}
public function update():void
{
var dx:Number = _pointB.x - _pointA.x;
var dy:Number = _pointB.y - _pointA.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var diff:Number = _length - dist;
var offsetX:Number = (diff * dx / dist)/* it means diff * cos(θ)*/ / 2;
var offsetY:Number = (diff * dy / dist)/* it means diff * sin(θ)*/ / 2;
_pointA.x -= offsetX;
_pointA.y -= offsetY;
_pointB.x += offsetX;
_pointB.y += offsetY;
}
public function render(g:Graphics):void
{
g.lineStyle(0);
g.moveTo(_pointA.x, _pointA.y);
g.lineTo(_pointB.x, _pointB.y);
}
}