Verlet积分反弹

3
我正在尝试学习Verlet积分,主要是因为我感到无聊,想要给我的常规“弹跳球”学习练习增添些调料。
我有一个简单的弹跳球Canvas/HTML5页面,网址是http://sandbox.electricgrey.com:8080/physics/。如果你点击它,你会注意到球并不总是反弹到相同的高度。有时它会更高,有时会更低。这是为什么呢?
这是因为我把它简化得太多了吗?我是否真的需要计算部分时间步长,以便我可以准确地知道/在哪里球碰撞,然后从那里继续呢?
附注:如果您对我的HTML或JavaScript有任何评论,我很愿意听取。我正在学习如何使用JavaScript编码,并希望确保我正在以正确的方式进行。

1
你不应该使用 const 来声明常量。请参考:https://developer.mozilla.org/en/JavaScript/Reference/Statements/const,特别是 "const 是一个 Mozilla 特有的扩展,它不被 IE 支持,但自 Opera 9.0 和 Safari 以来已经部分支持。" - Yi Jiang
谢谢你的建议。我已经修改了代码,不再使用const。 - Mike Cooper
看起来链接已经失效了。本来想看看你在说什么的。 - Drew Noakes
抱歉,@DrewNoakes,我认为这段代码已经不见了。如果我再找到它,我会在这里重新发布。 - Mike Cooper
2个回答

1
在Verlet算法中,最重要的是计算下一步所采取的时间步长。在Verlet算法中,您使用哪种类型:基本或速度?对于与地面的碰撞,您有什么想法?我发现每次碰撞点的高度都不相同。在这种情况下,您需要计算到达碰撞点所需的时间(t1),然后进行移动,并进行碰撞,最后再用时间(t_step-t1)进行移动。我在此模型的第一次实现中使用了此方法。

0

正如Asar所说,您可能需要更改步长。尝试类似以下的内容,并通过变化t来解决问题。

    function Vertex(x,y,vx,vy,t) {
        this.t = t
        this.x = x;
        this.y = y;
        this.px = x-vx*t;
        this.py = y-vy*t;

        .......
        this.tick = function() {
            ....
            var tx = this.x;
            var ty = this.y;
            this.x = this.x + (this.x - this.px) + this.ax * this.t;
            this.y = this.y + (this.y - this.py) + this.ay * this.t;
            ....
          }  
  ....
}  

你也可以通过改变以下方法来提高准确性,当球碰到地板时,反转球的速度。
if (this.y < this.r) {
    this.y = 2 * this.r - this.y;
    this.py = 2 * this.r - this.py;
}

如果球在时间步长的中间弹跳,那么它在时间步长的第一部分沿重力方向移动,但在时间步长的最后一部分远离重力方向移动。这两个贡献应该在某种程度上相互抵消。但是在您的代码中,您假设重力力量在整个时间步长期间都将球向前拉。您可以通过更改上述方法中包含“this.ax * this.t”项的公式来解决此错误。(但我不完全确定这个术语应该是什么样子)。
像这样调试程序的最佳方法是绘制一个图表,其中x轴表示时间,y轴表示总机械能。然后,您可以轻松确定您是否在弹跳或正常时间步骤期间失去了能量。

http://sandbox.electricgrey.com:8080/physics/physics.js


谢谢建议。现在我有点绕过了这个问题,但是当我重新考虑碰撞响应时,我会记住这点的。 - Mike Cooper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接