【问题标题】:Finding the intersection of 2 arbitrary cubes in 3d在 3d 中找到 2 个任意立方体的交集
【发布时间】:2013-07-07 15:23:21
【问题描述】:

所以,我想找出一个函数,让您确定两个任意旋转和大小的立方体是否相交。

如果立方体的旋转不是任意的(而是锁定在特定的轴上),则相交很简单;您可以通过检查它们的边界来检查它们是否在所有三个维度上相交,以查看它们在所有三个维度上是否交叉或在彼此内。如果它们交叉或仅在两个之内,则它们不会相交。此方法可用于确定任意立方体是否是交叉的候选对象,使用它们的最高/最低 x、y 和 z 来创建外部边界。

这是第一步。理论上,从这些信息中,我们可以分辨出它们彼此位于哪个“边”上,这意味着我们可以从交叉点中消除一些四边形(边)。但是,我不能假设我们有这些信息,因为立方体的旋转可能很难简单地确定。

我的想法是取每一对四边形,找到它们平面的交点,然后确定这条线是否与每对边的至少一条边相交。如果任何一对边有一条与它们的任何边相交的交线,则四边形相交。如果没有相交,则两个立方体不相交。

然后,我们可以通过平面相交线与其边相交的位置来确定第二个立方体上相交的深度。

不过,这只是推测。有没有更好、更有效的方法来确定这两个立方体的交集?我可以想到许多不同的方法来做到这一点,而且我还可以看出它们在所需的计算量方面可能会有很大的不同。

我目前正在使用 Java,但 C/C++ 解决方案也很酷(我可以移植它们);甚至是伪代码,因为这可能是一个大问题。

【问题讨论】:

  • Separating Axis Theorm 不是在 3D 中像在 2D 中一样工作吗?
  • 我认为可能。我没有想到这一点;我已经使用“3D 作为三组 2D”的版本。这可能比我想象的要简单!
  • 我打赌这对你有用。我很确定我在研究 2d 多边形交叉点时读过它
  • 似乎您会将 SAT 应用于每个面的法线对另一个立方体。如果任何测试失败,立方体不会相交。对于某些形状,我必须加倍,因为四边形是“弯曲的”(即三角形不齐平)。对于任何常规立方体/矩形棱镜对,看起来最多 16 次测试。
  • 听起来是对的。这是一个问题吗?如果是这样,您可以研究空间分区以减少需要检查的对。另外我不知道您的意图,但是立方体正在快速旋转或动画中的时间步长很好,请注意如果没有更高级的解决方案,您可能会错过交叉路口。

标签: java 3d geometry intersection


【解决方案1】:

要在三个维度上找到两个任意立方体的交点(接触),您必须分两个阶段进行:

  1. 检测冲突。这本身通常是两个阶段,但为简单起见,我们将其称为“碰撞检测”。

该算法可以是 SAT(分离轴定理),也可以是多面体扩展/缩减的一些变体。同样,为简单起见,我们假设您将使用 SAT。

我不会详细解释,因为其他人已经做过很多次了,而且比我做得更好。从中“带回家”的是,碰撞检测并非旨在告诉您在哪里发生了碰撞;只是它已经发生了。

  1. 检测到交叉点后,您需要计算接触点。这是通过多边形裁剪算法完成的。在这种情况下,让我们使用https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm

有更简单、更好的方法可以做到这一点,但 SAT 在 3d 中很容易掌握,SH 剪辑也很容易让您了解,因此对您来说是一个很好的起点。

【讨论】:

    【解决方案2】:

    你应该看看计算机图形学领域。他们有很多手段。例如。 Weiler–Atherton clipping algorithm。还有许多数据结构可以为您简化流程。提到AABB(Axis-aligned bounding boxes)。

    【讨论】:

    • 是的,我在我的问题中使用(并描述)AABB。
    • 是的,有点。使用 AABB,您可以验证任意形状是否 相交,如果相应的 AABB 不 相交。如果他们这样做,你必须做进一步的测试。阅读计算机图形学,我相信你会找到合适的解决方案!
    【解决方案3】:

    尝试使用分离轴定理。它应该像在 2d 中一样适用于 3d。

    【讨论】:

    • 显然,您需要将 SAT 应用于每个立方体的每个面,并与另一个立方体的八个点相对。我看到了很多几何示例,但在代码方面却一无所获。
    【解决方案4】:

    如果您从立方体的侧面创建多边形,那么另一种方法是对它们使用构造空间几何 (CSG) 操作。通过构建每个立方体的二进制空间分区 (BSP) 树,您可以对它们执行交集。交集的结果是一组表示交集的多边形。在您的情况下,如果多边形的数量为零,那么立方体不会相交。

    我要补充一点,这种方法可能不是一个好的实时解决方案,但您没有说明这是否需要在帧刷新时间内发生。

    由于移植是一个选项,您可以查看位于

    的执行 CSG 的 Javascript 库

    http://evanw.github.io/csg.js/docs/

    我已将此库移植到 C#

    https://github.com/johnmott59/CGSinCSharp

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      相关资源
      最近更新 更多