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