【问题标题】:Finding the minimum translation vector using intersection points使用交点找到最小平移向量
【发布时间】:2014-01-29 15:07:47
【问题描述】:

我正在构建一个基于 Paper.js 的应用程序。
我有一个项目列表,每个项目都由一个顶级组和一堆作为孩子的路径组成。
我需要实现碰撞检测,目前的工作方式如下:

  1. 当一个项目被拖动时,它的组件(它所包含的路径)会使用 Path#getIntersections(path) 方法。

  2. 如果该方法返回一个非空数组(CurveLocations,它描述了交点),我就知道发生了碰撞。一世 停止拖动并组合项目。

  3. 如果返回的数组为空,则无需处理碰撞,因此无需中断拖动。我翻译(移动)拖动的项目 它被拖动的距离。

现在,我需要在第 2 步中执行以下操作:

检测到碰撞后,我需要将项目移动到最近的位置 “合法”位置(最接近当前鼠标位置,没有 重叠任何其他形状/边框)。

现在我可以着手实施 SAT 或 GJK 并在没有 getIntersections 方法的情况下解决它,但我这里唯一缺少的是 MTV(如果我没记错的话)。

有人可以确认这是否可能,如果是,那么如何?


更新

在摆弄了各种鼠标事件之后,我得出了一个当前(不完美)的解决方案:

  1. onMouseDown:保存鼠标偏移量(项目位置减去鼠标位置)

  2. onMouseDrag: 检查交叉路口。如果是这样,当检查返回 true 时,通过 event.delta.negate() 翻译拖动的对象。完成后,更新偏移量。
    如果没有检测到交叉点,只需将拖动的项目移动到鼠标位置减去偏移量。

  3. onMouseUp:与拖动事件中的相同,但如果未检测到碰撞则不执行任何操作。

这或多或少是有效的,除了它很紧张而且它不处理收容问题。
将在时间允许的情况下更新示例。

【问题讨论】:

    标签: javascript geometry collision-detection vector-graphics paperjs


    【解决方案1】:

    如果您只有两个形状并且它们都非常接近圆形和框并且具有相似的大小,您可以获取形状边界框的中心并将这些中心点用作方向向量。然后你逐渐将它移开,直到不再有交叉点。但是,如果您的形状像 U 或 O 围绕另一个较小的形状,则此方法可能不会给出最短距离。如果移开会撞到其他物体,也一样。

    所以我认为你真正需要的是一个数值解,它以圆形方式将形状从其中心点移开,随着直径的增加,直到不再有任何交叉点。

    另一个问题可能是当您的形状包含在另一个形状中时,您甚至不会有任何交叉点。所以我想使用hittest会更好。

    编辑: 这是我试图用中间点解释的一个非常简单但没有很好优化的example。如果您没有看到任何覆盖,请重新加载它。对于圆形方式,检查变得更加复杂,因为您不仅会将形状移开,还会向所有其他方向移动。

    Edit2:第二个example 检查交叉点并将形状移到外面。如您所见,仅通过交叉点不足以检查障碍物是否大于拖动的项目。

    【讨论】:

    • “所以我认为你真正需要的是一个数值解,它以圆形方式将形状从其中心点移开,随着直径的增加,直到不再有任何交叉点。”你是说环保局吗?
    • 我不是 SAT、EPA、GJK 或 MTV 方面的专家,但我给你举了一个例子来说明我的意思。它可以被优化并且对于很多形状不是很有效,但我认为它有点工作。现在这仍然缺少循环的想法。但这只是圆圈移动方式的一种附加。也许它甚至没有必要。
    • In here 你可以明白我的意思:将重力和反弹设置为无,将摩擦力设置为最大并拖动(在球上方悬停时按住空格键)。当您拖动中心的框时,您可以看到所需的效果。这是通过 SAT 的实现来完成的。球被平移到鼠标位置,MTV 被编辑,因此它始终与框的边缘对齐。我想要的是获得相同的距离(而不是增量)并将其应用于拖动项目的位置。
    • 更正:我想要的是使用交叉点(不使用 SAT、GJK、EPA 等)获取 MTV。
    • 我认为交叉点还不够。因为当鼠标远离障碍物时,您将失去它们。我为此添加了一个示例。
    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2019-06-10
    • 2022-01-20
    • 2023-03-22
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    相关资源
    最近更新 更多