线性加速度运动:计算与建模

问题描述 投票:0回答:1

我有一个点,它以线性轨迹以静态加速度运动。我使用2种方法来预测点位置-

  1. 按公式计算:

    vx = v0 + a * t;

    x =(vx ^ 2-v0 ^ 2)/(2a)

  2. 建模:

    速度+ =加速度;

    位置+ =速度;

而且我有不同的结果。无法理解发生了什么问题,请参见代码:

<!DOCTYPE html>
<html>
<head>
</head>
<body style="margin: 0;padding: 0">
  <canvas id="id" width="1000" height="1000" style="border: 1px solid black;"></canvas>
  <script>
(function(){
var canvas = document.getElementById('id');
var ctx = canvas.getContext('2d');

var fps = 6;

function Point(x, color) {
	this.x = x;
	this.acceleration = {x: 0};
	this.speed = {x: 0};
	this.color = color;
}

Point.prototype.update = function(ctx) {
	this.speed.x += this.acceleration.x;
	this.x += this.speed.x;
}
Point.prototype.draw = function(ctx) {
	ctx.beginPath();
	ctx.arc(this.x, 30, 5, 0, Math.PI * 2);
	ctx.stroke();
	ctx.fillStyle = this.color;
	ctx.fill();
}

var ix = 10;
var p = new Point(ix, 'red');
p.acceleration.x = 1;
var p2 = new Point(ix, 'blue');

function calculateShift(v0, a, t) {
	return (Math.pow((v0 + a * t), 2) - Math.pow(v0, 2)) / (2 * a)
}

var iteration = 0;
function step() {

  iteration++;
  if(iteration > 20) {
	return;
  }
	
  ctx.clearRect(0, 0, 1000, 1000);
  p.update();
  var shift = calculateShift(0, p.acceleration.x, iteration);
  p.draw(ctx);
  p2.x = ix + shift;
  p2.draw(ctx);
  console.log(p.x, p2.x);
}

setInterval(function(){
	window.requestAnimationFrame(step);
}, 1000 / fps)


})()
</script>
</body>
</html>
javascript game-physics
1个回答
0
投票

看起来的问题在于迭代方法的精度。我更新了示例,看起来工作正常:

<!DOCTYPE html>
<html>
<head>
</head>
<body style="margin: 0;padding: 0">
  <canvas id="id" width="1000" height="1000" style="border: 1px solid black;"></canvas>
  <script>
(function(){
var canvas = document.getElementById('id');
var ctx = canvas.getContext('2d');

var fps = 60;

function Point(x, color) {
	this.x = x;
	this.acceleration = {x: 0};
	this.speed = {x: 0};
	this.color = color;
}

Point.prototype.update = function(ctx) {
	this.speed.x += this.acceleration.x;
	this.speed.y += this.acceleration.y;
	this.x += this.speed.x;
	this.y += this.speed.y;
}
Point.prototype.draw = function(ctx) {
	ctx.beginPath();
	ctx.arc(this.x, 30, 5, 0, Math.PI * 2);
	ctx.stroke();
	ctx.fillStyle = this.color;
	ctx.fill();
}

var ix = 10;
var p = new Point(ix, 'red');
p.lastUpdate = new Date().getSeconds();
p.acceleration.x = 1;
var p2 = new Point(ix, 'blue');

function calculateShift(v0, a, t) {
	return (Math.pow((v0 + a * t), 2) - Math.pow(v0, 2)) / (2 * a)
}

var iteration = 0;
var ts = new Date().getTime();
function step(timestamp) {

  iteration++;
	if(iteration > 2025) {
		return;
	}
  ctx.clearRect(0, 0, 1000, 1000);
	var s = new Date().getSeconds();
	if(s !== p.lastUpdate) {
	p.lastUpdate = s;
  p.update();
  }
  var shift = calculateShift(0, p.acceleration.x, (new Date().getTime() - ts) / 1000);
  p.draw(ctx);
  p2.x = ix + shift;
  p2.draw(ctx);
  console.log(p.x, p2.x);
}

setInterval(function(){
	window.requestAnimationFrame(step);
}, 1000 / fps)


})()
</script>
</body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.