1

To memorize spacial coordinates of a point, which way is more correct?

This,

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

Or this,

//       x    y    z
spacial[100][200][10] = 1; // 1 set that a point is present
Sam
  • 7,252
  • 16
  • 46
  • 65
xdevel2000
  • 20,780
  • 41
  • 129
  • 196
  • 1
    Why close lool? Please see this answer and my comment: http://stackoverflow.com/a/19541461/529543 75-78Mb allocating can be a bit waste of resources, but a bool[] recuce to 18Mb , and a bit level management to under 3Mb ! I would store those 3Mb instead of iterating the list. –  Oct 23 '13 at 12:41
  • see the 3Mb implementation: http://stackoverflow.com/a/19542553/529543 fix the indexes if is wrong –  Oct 23 '13 at 13:08

4 Answers4

3

That depends on the usage scenario of your code. Creating 3-dimensional array is very expensive in terms of resources (memory) so you should only use it when you are creating voxel structures or you know that you will need to fill all of the points in the space x*y*z. For this case the code

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

makes more sense to use. It is also useful if you want to quickly find whether certain spacial coordinate exists.

For other cases you can create structure

struct Coord
{
    int x, y, z
}

and then create array of instances of this structure instead. This gives you more memory efficiency as you do not have to have every single coordinate represented (even if it isn't there). You can still use algorithms to search efficiently using octrees for searching but they are more complex to implement. You can find more information about octrees in my answer to another question.

Community
  • 1
  • 1
N A
  • 656
  • 3
  • 6
2

I would use the second one:

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

However there are more representations: with angles, radius, not only the coordinates, for more info check Wiki

2

Using 3D arrays means that you storing 1024x768x100=78 643 200 integer values ath the same time. Most of this values uses memory, but contains zeros - i think it is too bad for good performance.

I think you should use Lists<> to store only points, that contains valuable coords:

  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
}
Anatoly Nikolaev
  • 520
  • 3
  • 12
  • +1,good approach 78 Mb sometimes is considerable, sometimes I would allocate to be faster the operation. In your list want to iterate 78 643 200 units to find if there is or not? It can be reduced to bool[] or other bit level improvement if really the memory is short –  Oct 23 '13 at 12:38
  • No to check out if something exists by some coordinates i simple do this: ListResList=MyPoints.SelectAll(coord=>coord.x==100&&coord.y==250&&coord.z==500); ResList will contains Point3D or null, if nothing exists there. – Anatoly Nikolaev Oct 23 '13 at 12:55
  • I've alredy modified my post with this sample – Anatoly Nikolaev Oct 23 '13 at 13:05
  • I have added the 3MB implementation :) –  Oct 23 '13 at 13:08
0

I wrote a Java this time - as exception - a full code :) I havn't run probably I will miss something at indexing, but I would use similar than this, if there are more than 20 point to store. Over 1000 point there is no question what to use this or a list..

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;

    }
}