【问题标题】:Why does the box keep moving after the brakes are fully applied?为什么完全踩下刹车后盒子一直在移动?
【发布时间】:2019-10-30 17:09:21
【问题描述】:

我做了一个带有二次拖动的最小水平运动模拟器,可以找到here(用左右箭头键控制)。作为练习,除了施加力和阻力之外,我还尝试实施制动。它在按住空格键时起作用,但在释放后,盒子又开始以看似随机的方向低速移动。以下是我认为相关的代码:

let vt = 500 // terminal velocity
let amag = 1000 // magnitude of applied acceleration
let bmag = 1000 // magnitude of brake's acceleration
let drag = amag / (vt*vt) // coeffcient of quadratic drag

let x  = 0 // horizontal position
let vx = 0 // horizontal velocity

function update(timestamp) {
  let dt = ... // compute time delta from timestamp

  // current acceleration
  let ax = (keyStates.ArrowRight * amag) + (keyStates.ArrowLeft * -amag) - (keyStates[' '] * bmag * Math.sign(vx))

  // forward euler method; solves (x'(t), vx'(t)) = (vx(t), ax(t) - drag * vx(t)^2)
  x  += dt * vx
  vx += dt * (ax - Math.sign(vx) * drag * vx * vx)
}

【问题讨论】:

  • 制动应该取决于速度(作为线性摩擦术语)(除非您使用某些火箭发动机主动制动)。如果汽车处于静止状态,则踩刹车不会产生任何加速度。

标签: javascript 2d game-physics differential-equations calculus


【解决方案1】:

缓慢移动时,您的制动幅度大于vx。此外,您的制动力与您移动的方向相反。因此,制动不会 0-out vx,而是会在 0 附近反弹 vx

例如想象一下bmag = 1dt = 1vx = 2.6。而不是vx2.6 -> 1.6 -> 0.6 -> 0,而是去2.6 -> 1.6 -> 0.6 -> -0.4 -> 0.6 -> -0.4...

这在您刹车时并不明显,因为运动会相互抵消,因为它会不断地翻转方向。但是一旦你松开刹车,它会根据时间以0.6-0.4 继续,因此你观察到的“看似随机的方向”。

要解决此问题,只需将 vx 清零,而 bmag * dt > vx

  // current acceleration
  let ax = (keyStates.ArrowRight * amag) + (keyStates.ArrowLeft * -amag);

  // forward euler method; solves (x'(t), vx'(t)) = (vx(t), ax(t) - drag * vx(t))
  x  += dt * vx
  vx += dt * (ax - Math.sign(vx) * drag * vx * vx)

  if (keyStates[' '])
     if (Math.abs(vx) > dt * bmag)
       vx -= dt * bmag * Math.sign(vx);
     else
       vx = 0;

顺便说一句,感谢您提供可重现的示例和相关的小子集。它对潜在的回复者和未来的读者都有帮助。

【讨论】:

    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    相关资源
    最近更新 更多