我的重力模拟是在第1和第3象限中排斥物体

时间:2016-03-24 12:15:39

标签: javascript simulation physics

我正在创建简单的重力模拟。我使用Pixi.JS来渲染对象。我使用Math.atan2计算从物体A到物体B的矢量角度。由于某种原因,当物体位于某个角度时它不能正常工作 - 我得到一种排斥力而不是吸引力。



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);
&#13;
<script src="//darker.github.io/asteroids/demo-elastic-bounce/pixi.js"></script>
&#13;
&#13;
&#13;

我不确定我做错了什么。我试图改变加速度的符号,但它没有产生预期的效果。

1 个答案:

答案 0 :(得分: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。插入此内容的一个逻辑点是

  var deltaV = magnitude*dt/this.mass;

或参数传递幅度。