1

记忆一个点的空间坐标,哪种方式更正确?

这个,

int spacial[][][] = new int[1024][768][100];

// first point at
spacial[0][0][0] = 100; // x
spacial[0][0][1] = 200; // y
spacial[0][0][2] = 10;  // z

或这个,

//       x    y    z
spacial[100][200][10] = 1; // 1 set that a point is present
4

4 回答 4

3

这取决于您的代码的使用场景。创建 3 维数组在资源(内存)方面非常昂贵,因此您应该只在创建体素结构时使用它,或者您知道需要填充空间中的所有点x*y*z。对于这种情况,代码

int spacial[][][] = new int[1024][768][100];
spacial[100][200][10] = 1; // 1 set that a point is present

使用起来更有意义。如果您想快速找到某个空间坐标是否存在,它也很有用。

对于其他情况,您可以创建结构

struct Coord
{
    int x, y, z
}

然后创建此结构的实例数组。这为您提供了更高的内存效率,因为您不必表示每个坐标(即使它不存在)。您仍然可以使用算法来使用八叉树进行有效搜索,但它们实现起来更复杂。您可以在我对另一个问题的回答中找到有关八叉树的更多信息。

于 2013-10-23T12:13:43.873 回答
2

我会使用第二个:

//     x    y    z
spacial[100][200][10] = 1; // 1 set that a point is present

然而还有更多的表示:角度、半径,不仅仅是坐标,更多信息请查看 Wiki

于 2013-10-23T12:03:43.420 回答
2

使用 3D 数组意味着您同时存储 1024x768x100=78 643 200 个整数值。大多数这些值都使用内存,但包含零 - 我认为这对于良好的性能来说太糟糕了。

我认为您应该使用 Lists<> 仅存储包含有价值坐标的点:

  public struct Point3D
  {
  public   int x {get;set;}
  public   int y {get;set;}
  public   int z {get;set;}
  public   int value {get;set;}
 //any other properties....
  }

List<Point3D>MyPoints=new List<Point3D>();

//to check if something exists by my coordinates:

List<Point3D> ResultList=MyPoints.FindAll(coords=>coords.x==25&&coords.y==250&&coords.z==70);
if(ResultList.Count>0) //points exists
{
  // do something with ResultList[0], that should contains your point data
}
于 2013-10-23T12:17:41.770 回答
0

这次我写了一个Java——作为例外——一个完整的代码:)我没有运行可能我会在索引时错过一些东西,但如果要存储的点超过20个,我会使用与此类似的东西。超过 1000 点毫无疑问使用这个或列表..

public class Spatial {

    public static final int maxX = 1024;
    public static final int maxY = 768;
    public static final int maxZ = 100;

    // 1024x768x100= 78 643 200
    // int max value:2,147,483,647

    private byte[] indexData;

    public Spatial() {
        int totalDataCount = maxX * maxY * maxZ;

        int byteAarraySizeNeeded = totalDataCount / 8 + totalDataCount % 8;

        indexData = new byte[byteAarraySizeNeeded]; // inited with all 0
    }

    public void markPresent(int x, int y, int z, boolean present) {
        // TODO: check parameters!!! minimum and max values!

        int index = (z * 1 + y * maxZ + maxX * (maxX * maxY));
        // transform the index to our storage index : maybe a bug here, cheack t pls!

        int arrayIndex = index / 8 + index % 8;

        byte dataChunck = indexData[arrayIndex];

        if (present) { // bitwise Or with 1
            dataChunck = (byte) (dataChunck | (1 << index % 8));
        } else { // bitwise And with 0
            byte helper = (byte) (1 << index % 8);
            byte all1ExceptOne = (byte) (~helper & 0xFF);
            dataChunck = (byte) (dataChunck & all1ExceptOne);
        }
        // put back:
        indexData[arrayIndex] = dataChunck;
    }

    public boolean isPresent(int x, int y, int z) {
        // TODO: check parameters!!! minimum and max values!

        int index = (z * 1 + y * maxZ + maxX * (maxX * maxY));
        // transform the index to our storage index : maybe a bug here, cheack t pls!

        int arrayIndex = index / 8 + index % 8;

        byte dataChunck = indexData[arrayIndex];

        return (dataChunck & (1 << index % 8)) > 0;

    }
}
于 2013-10-23T13:06:54.223 回答