【问题标题】:Check if a point is inside an arbitrary hexahedron检查一个点是否在任意六面体内
【发布时间】:2022-06-24 06:20:13
【问题描述】:

我正在编写一个 3D 有限元代码,我面临以下问题:

如果我取一个任意点(比如 x),我如何确定它在哪个元素中?

这可以简化为:如何检查任意点 (x) 是否位于(六面体)元素的内部或外部?

我已经找到的:

与上述两种方法相反,我的问题既不是直角也不是平行面。

问题草图:

符号:(再次说明:虽然草图显示了一个规则的形状,但我们的六面体被假定为一般形状)

  • 8节点六面体拓扑,节点数:0,..,7

  • 轴:r,s,t

                      t
                      |
             4--------|-------------7
            /|        |            /|
           / |        |           / |
          /  |        |          /  |
         /   |        |         /   |
        /    |        |        /    |
       /     |        |       /     |
      5----------------------6      |
      |      |        |      |      |
      |      |        o------|---------s
      |      |       /       |      |
      |      0------/--------|------3
      |     /      /         |     /
      |    /      /          |    /
      |   /      /           |   /
      |  /      /            |  /
      | /      r             | /
      |/                     |/
      1----------------------2
    

我们可用的数据:

  • 节点坐标(向量 P0 到 P7)
  • 我们要检查的点的坐标(比如说 Px)

此外,我们假设节点的顺序如上图所示。

到目前为止我的方法/解决方案:

  1. 计算表面(向外)法线向量

    使用叉积,例如。对于 r_pos_normal_vec(指向平面外)

    r_pos_normvec = (P2-P1) x (P5-P1)

    对于 r_neg_normal_vec

    r_neg_normvec = (P4-P0) x (P3-P0)

    s 和 t 方向类似

  2. 检查两个对角节点(我选择了节点0和节点6)

    • 对于节点0

      • 计算从P0到Px的向量:

        P0x = Px - P0

      • 计算 P0x 的内部产品和与节点 0 相邻的表面

    • 对于节点1

      • 与节点 0 的方案相同,但使用 P1 代替 P0 和法线向量的正对应项
  3. 如果所有 6 个(来自 node0 的 3 个和来自 node1 的 3 个)内积导致负值 -> 该点在六面体内部。

问题:

我在我的代码中实现了上述功能并运行了一些测试。 它似乎有效,从数学方面我很有信心。

请讨论我的方法,我很高兴任何提示/线索/建议/错误修复...... 有什么方法可以让这更快吗? 替代解决方案?

注意:

  • 为了加快算法速度,可以先进行复选框检查:
    • 围绕六面体构造一个矩形框:
    • 获取每个方向上节点坐标的最小值和最大值。
    • 如果要检查的点 (x) 在此(较大的)框之外,则它不能在六面体内。

【问题讨论】:

    标签: geometry computational-geometry mesh


    【解决方案1】:

    对于任何凸多面体,建立面的隐式方程(f.i. 三点平面),形式为ax+by+cz+d=0

    当你将一个已知点的坐标插入到表达式ax+by+cz+d中时,你会得到一组符号。如果产生相同的符号,则任意点在内部。


    更新:

    为了获得最佳性能,您还可以考虑使用轴对齐的边界框来快速拒绝。这只有在许多点都在外面时才有意义。让 sur 使用快捷评估,以便提前拒绝。

    请注意,诸如X<Xmin 之类的拒绝测试只不过是针对方程平面X-Xmin=0 的上述符号测试。

    【讨论】:

    • 不需要在隐式平面方程上进行代数运算...使用向量以更方便的方式执行相同的操作...dot( p-p(i) , n(i) ) 的符号在所有方面都相同i 其中@987654327 @ 是边的任何顶点,n(i) 是它的法线(叉积)......唯一的条件是所有法线都指向相同的方向(所有外部或内部)...
    • @Spektre:“建立隐式方程”和“使用向量”之间严格没有区别,在这两种情况下,您基本上是在计算相同的行列式。所有法线指向同一方向的条件与我给出的条件相同(您是否将所有符号更新为相同或保持原样,这是一个口味问题)。使用内部点是避免符号错误的万无一失的方法。
    • 我知道(这就是我所说的using vectors does the same ...)它的普通人(尤其是新手)在以向量形式重写时不明白如何处理代码中的ax+by+cz+d=0 等方程它直截了当......这也是为什么我没有添加答案,因为这将是相同的方法(而是我赞成你的正确方法)
    • @Spektre:我是一个无可救药的优化爱好者,所以我大部分时间都会使用预先计算的系数宣传成本最低的表达式。
    • 感谢你们!使用隐式方程的方法适用于具有任意数量节点/面的更多物体,我会记住这一点!在我的特殊情况下,我知道我所有的身体都是六面体,因此我想利用我的方法中所述的知识。我将尝试并比较这两种想法的计算时间。计算时间很重要,因为我正在做有限元并且需要多次重复该检查算法。
    【解决方案2】:

    我个人更喜欢你的方法,但是如果六面体仅限于平行六面体,还有一种方法可以解决这个问题。因此,您可以将 P 在框架 $(0; e_1; e_2; e_3)$ 中的坐标转移到 $(P_0, P_0P_1,P_0P_3,P_0P_4)$。我们称它为$(a,b,c)$,那么点就在那个平行六面体上 if $a,b,c > 0 a \in [0,1], a+b+c \in [0,1] $。

    【讨论】:

    • 是的,这是真的!如果您可以假设您的形状是平行六面体。不幸的是,我的问题中的形状是任意形状的六面体。我不能假设直角或平行平面。
    • 这应该是评论,而不是答案。
    【解决方案3】:

    因为您提到您希望能够处理任意六面体,所以我认为如果您调整您的 s、r 和 t 法线以解决略微扭曲的面,您的过程可能会得到改进。我会通过对 r 法线(和 s 和 t 类似)进行以下更改来做到这一点:

    r_pos_normvec = (P6-P1) x (P5-P2)

    r_neg_normvec = (P7-P0) x (P4-P3)

    这对于您将节点 6 移向节点 7(例如 0.9xP6)并在 0.95xP6 处有一个点的情况非常重要。如果没有翘曲校正,我相信您会错误地将点确定为六面体内部。

    【讨论】:

      猜你喜欢
      • 2014-12-12
      • 2012-02-11
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      相关资源
      最近更新 更多