1

I have a C++ raycaster, which inserts millions of points into a range of (-1,-1,-1) to (1,1,1). To avoid inserting duplicate points into the vertex buffer i want to check if a certain range already holding a point.

Thats how i setup my grid:

const int size = 500 * 500 * 500;
bool *grid = new bool[size];

for(int i = 0; i < size; i++)
  grid[i] = false;

unsigned double divide = 2.0 / size;

Now i want to check intersection points to add:

// In my code i handle negative and positive cases
int  x = intersection.X / divide;
int  y = intersection.Y / divide;
int  z = intersection.Z / divide;

if(!grid[x * y *z])
  //insert
else
  //discard

The problem iam facing is that divide is always 0, because size is too high. But i can't get how i can solve that. Iam already using unsigned double for.

vachee
  • 395
  • 1
  • 4
  • 15
  • There's no such thing as an unsigned double. I'm not sure how that even compiles. Also you're mixing types. 2.0 / size, where size is an int. I assume divide is unsigned. In that case divide will be zero if size > 2 (rounding). – Robinson Jun 28 '15 at 15:44
  • can you explain a little bit the purpose of `divide`? By default, `grid` is allocated with `false` so no need for the `for` loop. – mazhar islam Jun 28 '15 at 15:48
  • Make it a `multiply = size / 2.0; int x = intersection.X * multipliy;` Or simply `intersection.X * size / 2` – Igor Tandetnik Jun 28 '15 at 15:51

3 Answers3

2

You need to use a 3-dimensional array to store your boolean values.

How to initialize 3D array in C++

Also, your method of x * y * z to index your array won't work because there are multiple solutions for the same index (3 * 4 * 5 = 4 * 3 * 5).

Community
  • 1
  • 1
0

Assuming your points (x,y,z) have integer coordinates, you can just rewrite them as numbers in 3-nary system. Basically, it just implies adding +1 to each coordinate:

(x,y,z) --> x+1,y+1,z+1
(-1,1,0) --> 021
(1,1,1) ---> 222
(-1,-1,-1) --> 000

In this way, every point is unique, and the values range from 000 to 222, which is 3^3 = 27 different values.

So, you can just store an array of 27 values:

bool grid[27];
/* initialize to false, e.g. memset(grid, false, sizeof(grid)) */

if(!grid[9*(x+1) + 3*(y+1) + z]) // converting to ternary
   //insert
else
   //discard

You are welcome! ;)

Eric Gopak
  • 1,663
  • 1
  • 13
  • 26
0

Thank you for your answers. I missed a few things in my solution and reworked it now.

I use a 3D grid now and calculate my gridsize, which has the name divide

const int value = 500;

bool ***grid = new bool**[value];
for(int i = 0; i < value; ++i)
{
  grid[i] = new bool*[value];
  for(int j = 0; j < value; ++j)
  {
    grid[i][j] = new bool[value];
  }
}

double divide = 2.0 / value;

Because my point cloud region goes from (-1,-1,-1) to (1, 1, 1) i map it go from (0, 0, 0) to (2, 2, 2) and calculate the gridcell amount. The casts are dirty, i will avoid them when i know my exactly resolution.

     Vector3F gridIntersection(intersection.X + 1.0f, intersection.Y + 1.0f, intersection.Z + 1.0f);

      x = (int) ((double) gridIntersection.X / divide);
      y = (int) ((double) gridIntersection.Y / divide);
      z = (int) ((double) gridIntersection.Z / divide);

      if(!grid[x][y][z])
      {
        grid[x][y][z] = true;
      }

With that i have a ~119 MB memory usage. I will also improve it by using char instead of bool, to check for multiple members in a cell.

vachee
  • 395
  • 1
  • 4
  • 15