用于空间坐标的3D数组

时间:2013-10-23 12:00:15

标签: c# java c++

要记住点的空间坐标,哪种方式更正确?

此,

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 个答案:

答案 0 :(得分: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
}

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

答案 1 :(得分:2)

我会使用第二个:

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

然而,有更多的表示:角度,半径,不仅是坐标,更多信息检查维基

答案 2 :(得分: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
}

答案 3 :(得分: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;

    }
}