我正在创建简单的重力模拟。我使用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;
我不确定我做错了什么。我试图改变加速度的符号,但它没有产生预期的效果。
答案 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。)您对速度的更新还需要时间步dt
,v += a*dt
。插入此内容的一个逻辑点是
var deltaV = magnitude*dt/this.mass;
或参数传递幅度。