【问题标题】:3D array for spacial coordinates [closed]空间坐标的 3D 数组
【发布时间】:2013-10-23 21:06:54
【问题描述】:

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

这个,

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

【问题讨论】:

标签: c# java c++


【解决方案1】:

这取决于您的代码的使用场景。创建 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 的回答中找到有关八叉树的更多信息。

【讨论】:

    【解决方案2】:

    我会使用第二个:

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

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

    【讨论】:

      【解决方案3】:

      使用 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
      }
      

      【讨论】:

      • +1,好的方法 78 Mb 有时相当可观,有时我会分配更快的操作。在您的列表中想要迭代 78 643 200 个单位以查找是否存在?如果内存真的很短,它可以减少到 bool[] 或其他位级别的改进
      • 不检查是否存在某些坐标我简单地这样做: ListResList=MyPoints.SelectAll(coord=>coord.x==100&&coord.y==250&&coord.z= =500); ResList 将包含 Point3D 或 null,如果那里不存在任何内容。
      • 我已经用这个示例修改了我的帖子
      • 我已经添加了 3MB 的实现 :)
      【解决方案4】:

      这次我写了一个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;
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多