【问题标题】:JavaScript Separating Axis TheoremJavaScript 分离轴定理
【发布时间】:2012-05-01 06:25:05
【问题描述】:

我正在尝试使用 JavaScript 中的分离轴定理来检测两个正方形碰撞(一个旋转,一个不旋转)。尽我所能,我无法弄清楚这在 JavaScript 中会是什么样子,也找不到任何 JavaScript 示例。请帮忙,用纯数字或 JavaScript 代码解释会最有用。


更新:在研究了大量几何和数学理论后,我决定在 GitHub 存储库中推出一个简化的 SAT 实现。您可以在此处找到 JavaScript 中的 SAT 工作副本:https://github.com/ashblue/canvas-sat

【问题讨论】:

    标签: javascript collision-detection overlap


    【解决方案1】:

    变换多边形

    首先,您必须通过应用angle 的旋转来变换凸多边形(在本例中为正方形)的所有点,使它们都在同一个空间中。

    为了将来支持缩放、平移等。我建议通过矩阵变换来实现。您必须编写自己的 Matrix 类或找到一些已经具有此功能的库(我相信有很多选择)。

    那么你将徒劳地使用代码:

    var transform = new Matrix();
    transform.appendRotation(alpha);
    points = transform.transformPoints(points);
    

    其中pointsPoint 对象的数组。

    碰撞算法概述

    这就是所有之前你得到任何碰撞的东西。关于碰撞算法,标准做法是尝试使用以下步骤分离 2 个凸多边形(在您的情况下为正方形):

    • 对于每个多边形边(多边形 0 和多边形 1 的边):
      • 将两个 polgyons 分类为“在前面”、“跨越”或“在”边缘。
      • 如果两个多边形位于不同的侧面(1 个“前面”和 1 个“后面”),则没有碰撞,您可以停止算法(提前退出)。
    • 如果您到了这里,没有任何边缘能够将多边形分开:多边形相交/碰撞。

    请注意,从概念上讲,“分离轴”是垂直于我们用来对多边形进行分类的边缘的轴。

    根据边对多边形进行分类

    为了做到这一点,我们将根据边对多边形的点/顶点进行分类。如果所有点都在一侧,则多边形在该侧。否则,多边形跨越边缘(部分在一侧,部分在另一侧)。

    要对点进行分类,我们首先需要得到边缘的法线:

    // this code assumes p0 and p1 are instances of some Vector3D class
    
    var p0 = edge[0]; // first point of edge
    var p1 = edge[1]; // second point of edge
    var v = p1.subtract(p0);
    var normal = new Vector3D(0, 0, 1).crossProduct(v);
    normal.normalize();
    

    上面的代码使用边缘方向和z-vector的叉积得到法线。当然,您应该为每条边预先计算这个值。

    注意:法线表示与 SAT 的分离轴。

    接下来,我们可以通过首先使其相对于边缘(减去边缘点)并使用法线的点积来对任意点进行分类:

    // point is the point to classify as "in front" or "behind" the edge
    var point = point.subtract(p0);
    var distance = point.dotProduct(normal);
    var inFront = distance >= 0;
    

    现在,inFronttrue,如果该点位于前面或边缘,则 false 否则。

    请注意,当您循环遍历多边形的点以对多边形进行分类时,如果前面至少有 1 个点,后面至少有 1 个点,您也可以提前退出,因为那时已经确定多边形跨越边缘(而不是在前面或后面)。

    如您所见,您还有很多编码工作要做。找到一些带有 MatrixVector3D 类左右的 js 库,并使用它来实现上述内容。将您的碰撞形状(多边形)表示为 PointEdge 实例的序列。

    希望这能让你开始。

    【讨论】:

    • 还没有机会尝试这个,希望在接下来的几周内。据我所知,O 和所有矩阵转换库都非常慢。希望我不必从头开始写。
    • 有机会审查您的解决方案,这是完成实施的良好开端。对于那些希望使用它的人来说,还有很多事情要做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多