确定球体是否被其周围的其他球体完全包围

时间:2012-05-01 02:35:22

标签: java algorithm 3d

问题:给定一个球体列表,找到所有被球体完全包围的空格。

细节:这是我正在研究的一个问题,我试图确定蛋白质中的空洞。给出了构成蛋白质((x,y,z)坐标和半径的原子列表)。然后,我运行我的算法,通过检查探针(给定半径)是否可以放置在不与其他球体碰撞的位置来查找位于蛋白质边界内的所有空白空间。有两种类型的空白空间,空隙和空腔。空隙空间是可以通向蛋白质或在蛋白质外部的空间。腔是空的空间,完全被蛋白质原子包围。这是我们正在使用的样本“蛋白质”的图像。

protein

可以在三维here中查看。

在蛋白质的中心附近有一个空腔,你看到通过蛋白质的隧道将被认为是一个空隙空间,因为它没有被原子完全封闭。

示例:给定26个原子的列表,这些原子在三维网格中均匀地从(0,0,0)到(1,1,1)间隔开。每个原子的半径为0.25,并在任何轴上放置0,0.5或1。此时没有原子(0.5,0.5,0.5)。如果我们要绘制这些原子的3D图形,它将是一个像中心缺失的立方体形状。腔将被指定为(0.5,0.5,0.5),半径为0.25。可以假设这个腔被四周的蛋白质包围。

示例图片:image

请注意,上面只是立方体和蛋白质的2D表示。它实际上是3D。

对于更大和不规则形状的原子组,如何确定空隙空间与空腔?

我正在考虑实现一个递归算法来检查每个方向,看它是否可以达到图的最大和最小范围,但我不确定这是否是正确的方法。

额外:是否有不同的算法可以说示例中的腔实际上是一个空隙空间,因为有非常小的“路径”到达蛋白质的外部?空腔必须被原子完全包围才能存在。任何有蛋白质外部路径(任何方向,不一定是直线)的空隙都不会被视为空洞。

1 个答案:

答案 0 :(得分:4)

很酷的问题。这是一个应该做的技巧:

符号:

  • 让我们调用我们的可移动范围S
  • diam(X)
  • 的球体直径写X
  • dist(X,Y)代替XY的距离;这与从X的中心到Y的中心的距离减去半径的总和相同。

算法:

  1. 对于任何两个不可移动的领域AB,请检查S是否可以直接在AB的中心之间传递(即diam(S) <= dist(A,B) 1}}?)。
  2. 如果是这样,对于其他所有领域C,请检查S是否可以同时触及所有三个领域ABC,如果有没有其他领域存在。如果S可以同时触及所有3,请在ABC的中心之间绘制一个三角形。
    • 可以通过多种方式检查。一种相当简单的方法:触摸SA同时B中心的可能位置形成一个圆圈。你想知道这个圆圈上是否有一个距离diam(S) + diam(C)中心C小于S的点。这很简单。
  3. 问题现在减少了问题:三角形是否将S中心的初始位置与无穷大分开?您可以一次回答这个连接的组件。实际上,您甚至可以一次回答这个“边连接”组件,如果任何两个非顶点可以通过不通过任何顶点的路径链接,则组件是边连接的。您可以通过简单的图搜索来计算这些组件。
  4. 对于给定的边连通分量,您需要确定该分量是否将S的中心与无穷大分开。您可以通过以下几种方式执行此操作:
    • 计算组件的2 - homology,选择有效的生成器,并为每个生成器询问您的点和无穷大是否在循环的同一侧,可以使用方向类进行检查。
    • 或者,开始绘制组件:
      • 从可以从C到达的三角形开始,并从那里绘制可以到达的每个面。这有点微妙,但算法只是“从任何地方开始,排队边缘,将每条边缘交叉到面上,形成最小角度与该边缘,并在没有边缘时停止。”请记住,同一三角形的另一侧可能是形成最小角度的面。
      • 从无穷远处做同样的事。你穿过任何彩绘三角形了吗?如果是,你的球体可以逃脱。如果不是,则不能。
  5. 为什么会起作用

    第3步是正确的,因为如果你在AB之间的“边缘”滚动时没有碰到任何球体S,那么你可以到达该边缘的任何一侧。换句话说,任何阻止你进入无限远的位置都必须S触及至少3个球体。

    请注意,“异常”情况会产生一些细微之处,例如{{1}}同时接触4个球体时。在执行步骤3和步骤4之前,您可以通过重新三角化形状来避免这些细微之处。