如何在尺寸D的单位立方体/球体中均匀地生成一组K点

时间:2013-05-29 23:36:09

标签: java math geometry

我正在尝试生成一组K点,这些点在里面一个固定的空间中均匀分布,我认为单位球体或立方体是最简单的。对于2维而言这很容易,但不幸的是,当我们达到任意维D时要困难得多。

我认为这是在“准蒙特卡罗方法”中完成的,但我一直无法找到一个公式,甚至不能说明这是否是一个容易处理的问题。任何输入将不胜感激。

4 个答案:

答案 0 :(得分:5)

要看到计算最佳案例“非常微不足道”,请查看论文Dense Packings of Equal Spheres in a Cube,该论文解决了3D立方体中点的子案例:它具有精确解决方案和“最知名”解决方案,最多只能达到28个分。

它确实提供了一种用于找到这些最佳间隔配置的算法,他们称之为“随机台球”程序。但是我不知道这是否可以适应球体,更高尺寸或更大数量的点。

Finite Packing and Covering一书中可能会涵盖更一般情况的某些方面 - (我没有副本,所以无法验证。)

2D案例更易于处理,您可以在维基百科上查看the squarethe circle的更多详细信息。

答案 1 :(得分:4)

这取决于“均匀”的含义。一种方法是随机定位点,然后使用牛顿运动方程的数值积分器模拟阻尼介质中的粒子运动,其中粒子和边界是相互排斥的。这当然会允许任何边界形状。

答案 2 :(得分:1)

让我们考虑一下立方体,因为它更容易(我原来说容易,哈哈)。我认为这是你想要的(3D):

enter image description here

一侧的点数是n = floor(K 1 / D )。那么点之间的间距是1 /(n-1),假设角和边是包含的。我打算为这种网格方法提供一些代码,但它非常难看并且解决方案并不理想。

答案 3 :(得分:1)

我不确定我是否完全明白你的问题但是我的理由就是这样。

public static List<int[]> getEvenSpacedPoints(int x0, int x1, int y0,
        int y1, int z0, int z1, int samplePerSide) {

    List<int[]> list = new ArrayList<>();
    int xSpacing = (x1 - x0) / samplePerSide;
    int ySpacing = (y1 - y0) / samplePerSide;
    int zSpacing = (z1 - z0) / samplePerSide;

    for (int i = 0; i < samplePerSide; i++) {
        for (int j = 0; j < samplePerSide; j++) {
            for (int w = 0; w < samplePerSide; w++) {
                int xPoint = xSpacing * i;
                int yPoint = ySpacing * j;
                int zPoint = zSpacing * w;
                int[] point = new int[] { xPoint, yPoint, zPoint };
                list.add(point);
            }
        }

    }
    return list;
}

List<int[]> setOfSamplesFromCube = getEvenSpacedPoints(0, 10, 0, 10, 0,
            10, 5);
    for (int[] point : setOfSamplesFromCube) {
        String ret = "";
        for (int value : point) {
            ret += value + ",";
        }
        System.out.println(ret);
    }

输出:

0,0,0,
0,0,2,
0,0,4,
0,0,6,
0,0,8,
0,2,0,
0,2,2,
0,2,4,
0,2,6,
0,2,8,
0,4,0,
0,4,2,
0,4,4,
0,4,6,
0,4,8,
0,6,0,
0,6,2,
0,6,4,
0,6,6,
0,6,8,
0,8,0,
0,8,2,
0,8,4,
0,8,6,
0,8,8,
2,0,0,
2,0,2,
2,0,4,
2,0,6,
2,0,8,
2,2,0,
2,2,2,
2,2,4,
2,2,6,
2,2,8,
2,4,0,
2,4,2,
2,4,4,
2,4,6,
2,4,8,
2,6,0,
2,6,2,
2,6,4,
2,6,6,
2,6,8,
2,8,0,
2,8,2,
2,8,4,
2,8,6,
2,8,8,
4,0,0,
4,0,2,
4,0,4,
4,0,6,
4,0,8,
4,2,0,
4,2,2,
4,2,4,
4,2,6,
4,2,8,
4,4,0,
4,4,2,
4,4,4,
4,4,6,
4,4,8,
4,6,0,
4,6,2,
4,6,4,
4,6,6,
4,6,8,
4,8,0,
4,8,2,
4,8,4,
4,8,6,
4,8,8,
6,0,0,
6,0,2,
6,0,4,
6,0,6,
6,0,8,
6,2,0,
6,2,2,
6,2,4,
6,2,6,
6,2,8,
6,4,0,
6,4,2,
6,4,4,
6,4,6,
6,4,8,
6,6,0,
6,6,2,
6,6,4,
6,6,6,
6,6,8,
6,8,0,
6,8,2,
6,8,4,
6,8,6,
6,8,8,
8,0,0,
8,0,2,
8,0,4,
8,0,6,
8,0,8,
8,2,0,
8,2,2,
8,2,4,
8,2,6,
8,2,8,
8,4,0,
8,4,2,
8,4,4,
8,4,6,
8,4,8,
8,6,0,
8,6,2,
8,6,4,
8,6,6,
8,6,8,
8,8,0,
8,8,2,
8,8,4,
8,8,6,
8,8,8,

这包括起点(如果想省略则在1上开始循环)并且是“简单”因为我传递给它的立方体具有可被5整除的漂亮边,否则整数除法会破坏这个,但你可以看到如何轻松更改返回双列表。

我将开始尝试D维案例..