In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

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);
    }



}