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: 調和振動子シミュレーション(ラグランジュの運動方程式)

IK的な
/**
 * Copyright Nos_lkSsvOhB ( http://wonderfl.net/user/Nos_lkSsvOhB )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/o1A0
 */

// forked from Nosuke_lkSsvOhB's  調和振動子シミュレーション(ラグランジュの運動方程式)
package {
    import flash.display.*;
    import flash.events.Event;
    import com.bit101.components.*;

    public class Oscillator extends Sprite {
        private var i:Number;
        private var j:Number;
        private var n:int=5;
        private var k:Number=5000;
        private var nl:Number=50;
        private var dt:Number=0.001;
        
        private var ox:Number=230;
        private var oy:Number=230;
        
        private var m:Array=new Array();
        private var x0:Array=new Array();
        private var x1:Array=new Array();
        private var x2:Array=new Array();
        private var y0:Array=new Array();
        private var y1:Array=new Array();
        private var y2:Array=new Array();
         
        private var r:Number=10;
        //バネ描画用変数
        private var w:Number=nl;    //width
        private var h:Number=10;    //height
        private var di:Number=5;    //分割数
        private var s:Number=12;    //span
        private var p:Number=(w-2*s)/di;   //pitch
        private var t:Number=10;
        private var sig:Number;
        private var lx:Array=new Array();
        private var ly:Array=new Array();

        private var sp:Array=new Array();
        private var b:Array=new Array();
        private var sli:HUISlider;        
        public function Oscillator() {
            sli = new HUISlider(this, 10, 10, "Number", onChange);
            sli.value=n;
            sli.maximum=20;
            sli.minimum=2;
            init(n);
        }

        private function init(nm:Number):void {
            n=nm;

            for(j=0;j<n-1;j++){
                sp[j] = new Sprite();
                sp[j].graphics.lineStyle(2, 0x000000, 1, false, LineScaleMode.NONE);
                sp[j].graphics.moveTo(-w/2,0);
                sp[j].graphics.lineTo(-w/2+s,0);
                sp[j].graphics.lineTo(-w/2+s+p/4,-h/2);
                for(t=1, sig=1;t<2*di;t++,sig*=-1){
                  sp[j].graphics.lineTo(-w/2+s+p/4+t*p/2,sig*h/2);
                }
                t--;
                sp[j].graphics.lineTo(-w/2+s+p/4+t*p/2+p/4,0);
                sp[j].graphics.lineTo(-w/2+s+p/4+t*p/2+p/4+s,0);
                addChildAt(sp[j],j);
                sp[j].x=-200;
                sp[j].y=-200;
            }
            
            for(i=0;i<n;i++){
                m[i]=1;
                b[i] = new Sprite();
                b[i].graphics.beginFill(0xFFFFFF*Math.random());
                b[i].graphics.drawCircle(0,0,r);
                b[i].graphics.endFill();
                addChildAt(b[i],(i+n-1));
                x0[i]=mouseX+(ox-mouseX)/(n-1)*i;
                x1[i]=mouseX+(ox-mouseX)/(n-1)*i;
                y0[i]=mouseY+(oy-mouseY)/(n-1)*i;
                y1[i]=mouseY+(oy-mouseY)/(n-1)*i;
                b[i].x=x1[i];
                b[i].y=y1[i];
            }
            
            addEventListener(Event.ENTER_FRAME,onEnter);
            
            
        }
        private function onEnter(event:Event):void {
            lx[0]=nl*Math.cos(Math.atan2(b[1].y - b[0].y, b[1].x - b[0].x));
            ly[0]=nl*Math.sin(Math.atan2(b[1].y - b[0].y, b[1].x - b[0].x));
            lx[1]=nl*Math.cos(Math.atan2(b[n-1].y - b[n-2].y, b[n-1].x - b[n-2].x));
            ly[1]=nl*Math.sin(Math.atan2(b[n-1].y - b[n-2].y, b[n-1].x - b[n-2].x));
        
            //i=0のとき
            x2[0]=2*x1[0]-x0[0]+k*(x1[1]-x1[0]-lx[0])*Math.pow(dt,2)/m[0];
            y2[0]=2*y1[0]-y0[0]+k*(y1[1]-y1[0]-ly[0])*Math.pow(dt,2)/m[0];
            //そのあいだ
            for(i=1;i<n-1;i++){
                x2[i]=2*x1[i]-x0[i]-k*(2*x1[i]-x1[i+1]-x1[i-1])*Math.pow(dt,2)/m[i];
                y2[i]=2*y1[i]-y0[i]-k*(2*y1[i]-y1[i+1]-y1[i-1])*Math.pow(dt,2)/m[i];
            }
            //i=n-1のとき
            x2[n-1]=2*x1[n-1]-x0[n-1]-k*(x1[n-1]-x1[n-2]-lx[1])*Math.pow(dt,2)/m[n-1];
            y2[n-1]=2*y1[n-1]-y0[n-1]-k*(y1[n-1]-y1[n-2]-ly[1])*Math.pow(dt,2)/m[n-1];
        
            //i=0のとき
            b[0].x=x2[0];
            b[0].y=y2[0];
            x0[0]=x1[0];
            x1[0]=mouseX;
            y0[0]=y1[0];
            y1[0]=mouseY;
            //それ以外
            for(i=1;i<n;i++){
                b[i].x=x2[i];
                b[i].y=y2[i];
                if(i!=n-1){
                    x0[i]=x1[i];
                    x1[i]=x2[i];
                    y0[i]=y1[i];
                    y1[i]=y2[i];
                }else{
                    x0[i]=x1[i];
                    x1[i]=ox;
                    y0[i]=y1[i];
                    y1[i]=oy;
                }
            }
            for(i=0;i<n-1;i++){
                sp[i].x=(b[i+1].x + b[i].x)/2;
                sp[i].y=(b[i+1].y + b[i].y)/2;
                sp[i].scaleX=Math.sqrt(Math.pow(b[i+1].x - b[i].x,2)+Math.pow(b[i+1].y - b[i].y,2))/nl;
                sp[i].rotation=180/Math.PI*Math.atan2(b[i+1].y - b[i].y, b[i+1].x - b[i].x);
            }
        }
        private function onChange(event:Event):void {
            for(i=0;i<n;i++){
                b[i].graphics.clear();
                if(i!=n-1){
                    sp[i].graphics.clear();
                }
            }
            var num:int=sli.value;
            init(num);
        }
    }
}