【问题标题】:Algorithm for placing points evenly inside sphere将点均匀放置在球体内的算法
【发布时间】:2019-12-13 02:34:07
【问题描述】:

如果我有一个中心 (x,y,z) 和半径 r 的球体,是否存在一种算法来在球体内放置 X 个点 (x,y,z)彼此最大化?

例如一个点将简单地放置在中间,两个点将放置在相对的边界上,三个点将在边界上以“三角形”形式放置等等。

正如已经指出的那样,不能为每个点找到彼此相等的距离。因此,要求是最大化点之间的最小距离。

更新:

以下代码在半径为 1.0 的球体内生成点,但不会最大化距离。

function getPoint() {
    var d, x, y, z;
    do {
        x = Math.random() * 2.0 - 1.0;
        y = Math.random() * 2.0 - 1.0;
        z = Math.random() * 2.0 - 1.0;
        d = x*x + y*y + z*z;
    } while(d > 1.0);
    return {x: x, y: y, z: z};
}

我想我之后需要某种迭代。我尝试使用 n 体问题作为灵感来应用力模型,虽然看起来很有趣,但效果并不好。

【问题讨论】:

  • 四面体格子?
  • “同时最大化占用空间”是什么意思?
  • 你接受随机的统一布局还是只接受一个格子?
  • 给定 4 个点,解是一个内接在球体中的四面体。但是对于 5 个或更多点,在 3D 中没有解决方案,其中 所有 对不同的点具有相同的距离(就像 2D 中没有 4 个或更多点的解决方案)。您想最大化不同点之间的最小距离吗?
  • 你是对的,这是一个更好的解释。

标签: algorithm 3d geometry


【解决方案1】:

刚刚更新,因为我忘记了这个问题:

由于统一方法对于 100 多个点已经足够好,并且由于有人计算了球体上从 1 到 99 点的点位置,因此解决方案是查找 [1:100] 的位置,或者生成点分布均匀。

【讨论】:

    【解决方案2】:

    该问题与packing identical spheres into a unit sphere 密切相关(也许这两个问题甚至是等价的):将半径为rn 球体打包成一个单位球体的解决方案,所有球体中心都在一个球体内半径为1-r,距离至少为2r。因此,将相同球体打包成单位球体的解决方案可以轻松转换为您的问题的解决方案。

    经过验证的将相同球体打包成球体的最佳解决方案只存在于n=12。所以我猜你也必须接受接近最佳的解决方案,至少对于n>12。就最优性而言,目前最著名的算法似乎是 Serial Symmetrical Relocation Algorithm for the Equal Sphere Packing Problem.

    【讨论】:

      【解决方案3】:

      对于一个随机点均匀分布在圆柱坐标(r,phi,z)的单位球体内,我们有

                 int[0,x] 2*r*pi*2*sqrt(1-r^2) dr
      P(r < x) = -------------------------------- = 1 - (1-x^2)^(3/2) =: F(x), x in [0,1]
                              4*pi/3
      

      逆函数F^-1(r) = sqrt(1-(1-r)^(2/3))将均匀分布在[0,1]中的随机变量U转换为如上分布为r的随机变量。由于1-UU 具有相同的分布,我们可以使用更简单的函数sqrt(1-r^(2/3))

      柱坐标的其他分量phiz均匀分布在各自的范围内。

      因此,我们得到 Python 代码,用于直接生成均匀分布在球内的点,如下所示:

      import math, random
      
      def randomUnitSpherePoint():
          # cylindrical coordinates
          rxy = math.sqrt(1 - random.uniform(0, 1)**(2./3.))
          phi = random.uniform(0, 2*math.pi)
          zAbsMax = math.sqrt(1 - rxy*rxy)
          z = random.uniform(-zAbsMax, zAbsMax)
          # cartesian coordinates
          x,y = rxy*math.cos(phi), rxy*math.sin(phi)
          return x,y,z
      
      def randomSpherePoint(center, radius):
          x,y,z = randomUnitSpherePoint()
          return center[0] + r*x, center[1] + r*y, center[2] + r*z
      

      注意:“标准”解决方案(在边界框内生成随机点并在球体内选择点)通常更有效,尤其是在使用伪随机数生成器时。

      【讨论】:

      • @YvesDaoust 查看添加的计算/推理
      • 虽然这似乎可行,但它似乎并没有创建彼此距离相等的点。虽然对于大型点集,这将是相同的,但对于小于 10 且半径较大的较小集,它可能会创建到该点的截然不同的距离。
      • @MortenGR 是的,这只是随机均匀分布,而不是具有定义距离的规则排列。我现在知道这不是您要求的...
      • 我已经更新了这个问题,使其更加准确。很抱歉描述模糊
      【解决方案4】:

      对于随机但均匀的放置,在球体的边界立方体中绘制均匀的随机点并接受球体内部的点。当你有足够的积分时停止。

      如果你想要一个有规律的安排,这个问题要困难得多。

      【讨论】:

      • 我不明白为什么有规律的安排更难 Yves。
      • 嗨,伊夫。我已经按照你的建议做了。我用一个简单的while循环生成点并丢弃1.0之外的值,然后乘以球体半径。问题是,就像你说的那样,定期安排比统一点更难归档。之后我尝试了不同的算法来对齐点,但运气不佳。
      猜你喜欢
      • 2011-07-21
      • 2020-04-10
      • 1970-01-01
      • 2013-03-30
      • 2016-07-13
      • 2019-06-29
      • 2021-09-12
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多