>我有一个点,它以静态加速度的线性轨迹移动。我使用 2 种方法来预测点位置 -
-
按公式计算:
vx = v0 + a * t;
x = (vx^2 - v0^2(/(2a(
-
建模方式:
速度 += 加速度;
位置 += 速度;
我有不同的结果。不明白出了什么问题,请参见代码:
<!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>
看起来问题出在迭代方法的精度上。我更新了示例,看起来它工作正常:
<!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>