2016-03-24 4 views
1

私は単純な重力シミュレーションを作成しています。私はPixi.JSを使ってオブジェクトをレンダリングします。私はMath.atan2を使って、オブジェクトAからオブジェクトBへのベクトルの角度を計算します。何らかの理由で、オブジェクトが特定の角度に置かれていると、正しく動作しません - 私は魅力的ではなく反発力を得ます。私の重力シミュレーションは、第1象限と第3象限のオブジェクトを反発しています

var renderer = PIXI.autoDetectRenderer(600, 500,{backgroundColor : 0x0}); 
 
document.body.appendChild(renderer.view); 
 

 
// create the root of the scene graph 
 
var stage = new PIXI.Container(); 
 

 
// create a texture from an image path 
 
var texture = PIXI.Texture.fromImage('http://pixijs.github.io/examples/_assets/basics/bunny.png'); 
 

 
var objects = []; 
 
// start animating 
 
animate(); 
 
function animate() { 
 
    requestAnimationFrame(animate); 
 
    // render the container 
 
    renderer.render(stage); 
 
} 
 

 
/** 
 
    the third argument, mass, must be in kilograms **/ 
 
function GravityWell(x,y,mass) { 
 
    this.sprite = new PIXI.Sprite(texture); 
 
    // center the sprite's anchor point 
 
    this.sprite.anchor.x = 0.5; 
 
    this.sprite.anchor.y = 0.5; 
 

 
    // move the sprite to the center of the screen 
 
    this.sprite.position.x = this.x = x; 
 
    this.sprite.position.y = this.y = y; 
 
    stage.addChild(this.sprite); 
 
    
 
    this.rotation = 0; 
 
    this.sprite.rotation = this.rotation; 
 
    
 
    this.vx = 0; 
 
    this.vy = 0; 
 
    
 
    this.mass = mass; 
 
} 
 
GravityWell.prototype.G = 6.674e-11; 
 
GravityWell.prototype.acceleration = function(object) { 
 
    var dist = (this.x-object.x)*(this.x-object.x)+(this.y-object.y)*(this.y-object.y); 
 
    if(dist>0) 
 
    return (this.G*this.mass*object.mass)/dist; 
 
    else 
 
    return 0; 
 
} 
 
// This should be correct according to http://gamedev.stackexchange.com/a/33710/25920 
 
GravityWell.prototype.angleTo = function(object) { 
 
    return Math.atan2(-this.x+object.x, -this.y+object.y); 
 
} 
 

 
GravityWell.prototype.accelerate = function(direction, magnitude) { 
 
    var deltaV = magnitude/this.mass; 
 
    this.vx += deltaV*Math.cos(direction); 
 
    this.vy += deltaV*Math.sin(direction); 
 
} 
 
GravityWell.prototype.move = function(dt) { 
 
    dt /= 1000; 
 
    this.x += this.vx*dt; 
 
    this.y += this.vy*dt; 
 
    this.sprite.position.x = this.x; 
 
    this.sprite.position.y = this.y; 
 
} 
 
// Creating objects 
 
var ship; 
 
objects.push(new GravityWell(300, 250, 1000000000)); 
 
objects.push(new GravityWell(400, 400, 20000)); 
 
objects.push(new GravityWell(100, 100, 20000)); 
 
objects.push(new GravityWell(400, 100, 20000)); 
 

 

 
var last = performance.now(); 
 
setInterval(function() { 
 
    var dt = performance.now() - last; 
 
    for(var i=0,l=objects.length; i<l; i++) { 
 
    var obj = objects[i]; 
 
    for(var j=i+1,l=objects.length; j<l; j++) { 
 
     var a = obj.acceleration(objects[j]); 
 
     if(a!=0) { 
 
     obj.accelerate(obj.angleTo(objects[j]), a); 
 
     objects[j].accelerate(objects[j].angleTo(obj), a); 
 
     } 
 
    } 
 
    } 
 
    for(var i=0,l=objects.length; i<l; i++) { 
 
    objects[i].move(dt*10000); 
 
    } 
 
    
 
}, 10);
<script src="//darker.github.io/asteroids/demo-elastic-bounce/pixi.js"></script>

私は私が間違っているのかわからないんだけど。私は加速のサインを変えようとしましたが、望みの効果はありませんでした。

答えて

1

コードにいくつかの誤りがあります。

1)dx = r*cos(phi)dy = r*sin(phi)場合、速度の更新に使用されるように、次いで

phi = atan2(dy, dx) 

、すなわち、引数の順序を逆に。

2)力ベクトル計算のためにあなたが

var dx = this.x-object.x; 
var dy = this.y-object.y; 

var dist = Math.sqrt(dx*dx+dy*dy); 

var deltaV = magnitude/this.mass; 

var deltaVx = dx/dist; 
var deltaVy = dy/dist; 

3のように、全く角度を必要としない)の速度のあなたのアップデートでは、時間ステップdtv += a*dtを必要とします。これを挿入する1つの論理ポイントは、

var deltaV = magnitude*dt/this.mass; 

、またはパラメータの受け渡しになります。

関連する問題