2016-03-24 8 views
1

Ich erstelle einfache Schwerkraft-Simulation. Ich benutze Pixi.JS, um die Objekte zu rendern. Ich verwende Math.atan2, um Vektorwinkel von Objekt A zu Objekt B zu berechnen. Aus irgendeinem Grund, wenn Objekte in bestimmten Winkeln liegen, funktioniert es nicht richtig - ich bekomme eine abstoßende Kraft statt anziehend.Meine Gravitationssimulation ist Objekte im 1. und 3. Quadranten abstoßen

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>

Ich bin nicht sicher, was mache ich falsch. Ich habe versucht, die Beschleunigung zu ändern, aber es hatte keinen gewünschten Effekt.

Antwort

1

Es gibt mehrere Fehler in Ihrem Code.

1.) Wenn dx = r*cos(phi)dy = r*sin(phi) und, wie in der Geschwindigkeitsaktualisierung verwendet, dann

phi = atan2(dy, dx) 

d.h. umgekehrte Reihenfolge der Argumente.

2.) Für die Kraftvektorberechnung Sie überhaupt den Winkel nicht benötigen, wie in

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.) Ihre Aktualisierung der Geschwindigkeiten muss auch die Zeit Schritt dt, v += a*dt. Ein logischer Punkt, um dies einzufügen, ist bei

var deltaV = magnitude*dt/this.mass; 

oder in der Parameterübergabe der Größenordnung.