JavaScript -分离轴定理-碰撞工作,但不响应



所以,我试图应用响应到我的SAT,圆-聚,聚-聚碰撞。我将本文中的代码移植到JavaScript中:

http://rocketmandevelopment.com/blog/separation-of-axis-theorem-for-collision-detection/

现在,检测适用于所有类型,但是响应失败并且以疯狂的速度和错误的角度运行,它不依赖于物体的质量(面积^2而不是质量)并且角速度不适用

JSFiddle(重力不应用于模拟,用箭头键移动),JS的第一部分是矢量,然后是物理,然后是Main。

这是我对形状的定义:(必须为"JSFiddle"添加一些代码链接:p)

var Circle = function(body, c, r, cor, cof) {
    this.body = body // Static or dynamic
    this.c = c; // Center
    this.r = r; // Radius
    this.m = getCMass(r); // Mass = Area
    this.v = new Vector(); // Velocity
    this.cor = cor; // Coefficient of restitution
    this.cof = cof; // Coefficient of friction
    this.a = 0; // Angle
    this.av = 0; // Angular velocity
    this.type = "Circle";
}
var Polygon = function(body, c, vs, cor, cof) {
    this.body = body // Static or dynamic
    this.c = c; // Center
    this.vs = vs; // Vertices
    this.m = getPMass(vs); // Mass = Area
    this.v = new Vector(); // Velocity
    this.cor = cor; // Coefficient of restitution
    this.cof = cof; // Coefficient of friction
    this.a = 0; // Angle
    this.av = 0; // Angular velocity
    this.type = "Polygon";
}
function getCMass(r) { // More like, getCArea
    return (r * r * Math.PI);
}
function getPMass(vs) {
    var area = 0;
    var j = vs.length - 1;
    for (var i = 0; i < vs.length; i++) {
        area += (vs[j].x + vs[i].x) * (vs[j].y - vs[i].y); 
        j = i;
    }
    return (area / 2);
}

所有的碰撞函数都给出了失败的响应结果,所以一定存在某种连接。

回到角速度,我知道如何旋转多边形,但我希望在碰撞后得到新的av:

px = x * cos(a) - y * sin(a); 
py = x * sin(a) + y * cos(a);

我还为线条和bezier做了一个很好的物理模拟器,它可能会有所帮助:http://murplyx.net/projects/csb/

所以对我来说最重要的部分是我要如何修正使速度和角度正确?(我用的是矢量而不是三角函数)然后我可以考虑质量和角速度。谢谢。我待在Box2D框之外。

编辑:增加计算面积^2的函数,使质量相等。

在圆碰撞函数getCCCol(a, b)中,你计算的是中心之间的向量a.center - b.center,然后你用一个标量来表示两个圆的重叠,这个标量沿着圆中心之间的向量以长度为单位测量。我不明白这个向量是什么意思,但它代表了一个长度或一种定向面积。

update()中,如果它们不固定,则在碰撞的情况下添加上面提到的圆的速度值。将速度和长度(或面积)相加是没有意义的。你真正想做的是改变物体的速度矢量取决于它们当前的速度,它们之间的接触平面,它们的质量,也许还有它们的弹性。这可能还需要向后运行模拟一段时间,以消除由于固定时间步长而导致的对象重叠。例如,对于两个质量相等的完全弹性圆,头朝上碰撞,你只需要反转速度矢量,但不添加任何东西,这取决于碰撞的几何形状。

同样适用于getPCCol(p, c)getPPCol(a, b),在那里你再次计算某种距离,然后在碰撞的情况下将其添加到速度中。这些值打算代表什么?

最后,没有一个问题,我可以指出你,将解决问题。在碰撞的情况下更新速度的代码与这个过程背后的物理原理不匹配。我还建议明确地引入一个时间步骤,因为您的位置更新步骤position = position + velocity实际上应该是position = position + velocity x timestep。通过明确这一点,即使你选择它为1,你也可以更容易地检查你的计算单位是否有意义。

重新考虑如何执行模拟可能也是一个好主意。而不是向前一个固定的时间步骤,然后在碰撞的情况下备份-你目前没有这样做,但你可能迟早要这样做-首先计算下一次碰撞的时间,然后只推进模拟到这一点。现在,如果速度很高,或者物体足够小,如果一个时间步长使一个物体在速度方向上的距离大于假定的碰撞伙伴的尺寸,那么你的物体就可以穿过对方。如果你正在模拟粒子,因此碰撞不是一个(大)问题,那么你的固定时间步长方法可能足够好,但如果你必须使用固定时间步长来处理碰撞,那就不够好了。

我希望这对你有所帮助,当然,如果有什么不清楚或需要进一步阐述的地方,你可以随时问我。


这就是我可能尝试实现刚体动力学的方式,即我将添加功能的顺序。每一步或多或少只增加一个功能,但它们都比听起来要复杂得多。每一步都有数千页的研究报告和数十或数百种实现方案。

  1. 没有角动量的粒子动力学

    定义粒子的质量,(质心)位置和速度。用一个简单的积分算法模拟它们的运动和对作用在质心上的力的响应。

  2. 具有角动量的粒子动力学

    加入惯性张量和角速度。考虑使用四元数。实现对作用在任何点上的力的响应,而不仅仅是质心

  3. 考虑碰撞的刚体动力学

    实现一个碰撞搜索算法,预测碰撞时间和碰撞点。使用像基于脉冲的接触模型这样的简单模型来计算碰撞响应。这可能需要引入时间步长细分。

  4. 考虑摩擦的刚体动力学

    添加一个简单的摩擦模型,如哥伦布摩擦

  5. 添加重力和其他力场

    这里你必须决定你是否想要一个恒定的引力,或者你是否也想计算物体之间的引力。你可以在第一步之后添加重力,因为它只是一个作用在质心上的力,但由于重力随着两个物体越来越近而变得无限,整个模拟很容易爆炸,即你的物体以很大的速度飞走。模拟重力和其他力场通常需要更先进的积分算法。一般来说,你会发现在模拟中添加更多的特性通常会增加对积分算法的要求,并且你会得到不稳定性。

相关内容

最新更新