【问题标题】:JavaScript - Separating Axis Theorem - Collision working, but not Response?JavaScript - 分离轴定理 - 碰撞工作,但不是响应?
【发布时间】:2014-06-27 09:59:47
【问题描述】:

所以,我正在尝试对我的 SAT、Circle - Poly、Poly - Poly 碰撞应用响应。我将本文中的这段代码移植到 JavaScript:

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

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

JSFiddle(模拟时没有应用重力,用方向键移动),JS中的第一部分是Vectors,然后是Physics,然后是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);

我还为线条和贝塞尔曲线制作了一个不错的物理模拟器,它可能会有所帮助:http://murplyx.net/projects/csb/

所以对我来说最重要的部分是我将如何修复以使速度与速度和角度正确匹配? (我使用的是向量而不是三角函数-.-)然后我可以考虑质量和角速度。谢谢。我不使用 Box2D。

编辑:添加了计算面积^2 以将质量设置为相等的函数。

【问题讨论】:

  • 270 -` 200` = 70 (rep) O_o
  • O_o 我一开始有 470 个代表 270 + 200 = 470 :P
  • 干得好。你正在赚钱和销售:)

标签: javascript vector physics collision


【解决方案1】:

在圆圆碰撞函数getCCCol(a, b) 中,您正在计算a.center - b.center,它是中心之间的向量,然后您通过一个标量对其进行缩放,该标量表示沿向量之间的长度以长度为单位测量的两个圆的重叠圆圈的中心。我无法理解这个向量应该是什么意思,但它代表一个长度或一种定向区域。

然后在update() 中添加 - 如果发生碰撞 - 如果圆圈不固定,则将上述值添加到圆圈的速度中。添加速度和长度(或面积)没有意义。你真正想做的是根据物体的当前速度、它们之间的接触平面、它们的质量以及它们的弹性来改变物体的速度矢量。由于您的固定时间步长,这可能还需要向后运行模拟一段时间以消除对象的重叠。因此,例如,对于两个质量相等的完全弹性圆碰撞头部,您只想反转速度矢量,但不根据碰撞的几何形状向它们添加任何东西。

getPCCol(p, c)getPPCol(a, b) 也是如此,您再次计算某种距离,然后在发生碰撞时将其添加到速度中。这些值打算代表什么?

最后,我无法指出一个可以解决问题的问题。发生碰撞时更新速度的代码与该过程背后的物理原理不匹配。我还真的建议明确地引入一个时间步,因为你的位置更新步 position = position + velocity 真的应该是 position = position + velocity x timestep。通过明确这一点,即使您选择它为一个,您也可以更轻松地检查您的计算单位是否有意义。

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

我希望这会有所帮助,当然如果有什么不清楚或需要进一步阐述,请随时提出。


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

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

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

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

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

  3. 带有碰撞的刚体动力学

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

  4. 带摩擦的刚体动力学

    添加一个简单的摩擦模型,例如 Coloumb 摩擦。

  5. 添加重力和其他力场

    在这里,您必须决定是只想拥有恒定的重力,还是还想计算物体之间的重力。您可以在第 1 步之后立即添加重力,因为它只是作用在质心上的力,但是因为随着两个物体越来越靠近,重力变得无限,整个模拟很容易爆炸,即您的物体以很大的速度飞走。模拟重力场和其他力场通常需要更高级的积分算法。一般来说,您会发现在模拟中添加更多特征通常会增加对集成算法的要求,并且会变得不稳定。

【讨论】:

  • 关于检查旧速度并添加新速度是对的,这就是我在 resCCCol 中所做的:jsfiddle.net/4M94x。所以我们可以跳过圆圈部分,但PC和PP仍然有同样的问题。如果您不理解他们输出的内容,您可能需要转到文章链接并检查 // 注释。我仍然不明白如何实现与我在下面小提琴中的 resCCCol 中所做的相同的事情作为多边形?
  • 另外谢谢,速度时间步长可能太高,错过了我现在不太关心的碰撞,所以稍后会,最重要的是获得新的正确速度.
  • 对 cme​​ts 的良好提示,有时您会错过显而易见的事情。事实证明,返回的值是我想的,但是链接的文章已经在圆圆碰撞代码中包含一个错误(或省略了一些部分),这让我很困惑。我稍后会更新我的答案,但本质上它如下 - 你只有代码来检测碰撞,但根本没有代码来处理它们。您的其他工作模拟让我相信您在物理模拟方面经验丰富,因此我没有寻找类似的东西。
  • 好吧,贝塞尔曲线显然不是我的代码,但我移植了它并实现了响应。但我并不是真正的物理大师。那么我的代码应该是什么样子的呢?因为我不明白它应该是什么样子。
  • 如果对物理学没有很好的理解,除非您找到一些可以移植的代码,否则您无法做到这一点。您缺少碰撞响应代码,如果您只看一下Wikipedia,您就会意识到这并不是微不足道的。我无法为您提供任何可以插入程序的代码,因为实现它可能需要几天甚至几周才能获得良好的结果。真实地模拟物理是一个相当困难的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多