tags:

views:

170

answers:

3

Hi everybody,

I want to create the 26 neighbors of a cubic-voxel-node in 3-d space. The inputs are the x,y,z position of the node and the size of the cube side . I am trying to do this using a for loop but haven't managed yet. I am quite newbie in programming please help me.

+8  A: 
for (int dz = z - 1; dz <= z + 1; ++dz)
{
  for (int dy = y - 1; dy <= y + 1; ++dy)
  {
    for (int dx = x - 1; dx <= x + 1; ++dx)
    {
      // all 27
      if ((dx != x) || (dy != y) || (dz != z))
      {
        // just the 26 neighbors
      }
    }
  }
}
Matt Cruikshank
You may need to do some boundary checking in edge cases, but you definitely answered the question. +1
e.James
Fix the typo: ++z,y,x should be ++dz,dy,dx respectively.
strager
The three loops must have "++dz", "++dy" and "++dx" at the end respectively; you don't want to change x,y,z themselves.
ShreevatsaR
Thanks a lot everybody - Dieter
dieter
@dieter, click the checkbox left of this answer to mark it as the right answer. Also, delete the answer you made below.
strager
+1  A: 

Here's a variant without nested loops. I've tried to use a similar to your question notation.

// g++ 26neighbours.cpp -o 26neighbours && 26neighbours 
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

namespace {
  struct Pos {
    double x, y, z;

    template<class Char, class Traits>
    friend std::basic_ostream<Char, Traits>& 
    operator<< (std::basic_ostream<Char, Traits>& out, const Pos& p)
    {
      return out << p.x << " " << p.y << " " << p.z;
    }

    explicit Pos(double x_ = 0, double y_ = 0, double z_ = 0) 
      : x(x_), y(y_), z(z_)
    {
    }
  };

  template <class OutputPosIterator, class InputPosIterator, class Number>
  void translate(OutputPosIterator first, OutputPosIterator last, 
      InputPosIterator delta, Number factor)
  {
    for ( ; first != last; ++first, ++delta) {
      first->x += delta->x * factor;
      first->y += delta->y * factor;
      first->z += delta->z * factor;
    }
  }
}

int main(int argc, char *argv[])
{
  const Pos delta[] = {
    // ruby -e"(-1..1).each{|i| (-1..1).each{|j| (-1..1).each{|k| printf(\"Pos(%2d,%2d,%2d),\n\", i, j, k) if (i!=0 || j!=0 || k!=0)}}}"
    Pos(-1,-1,-1),
    Pos(-1,-1, 0),
    Pos(-1,-1, 1),
    Pos(-1, 0,-1),
    Pos(-1, 0, 0),
    Pos(-1, 0, 1),
    Pos(-1, 1,-1),
    Pos(-1, 1, 0),
    Pos(-1, 1, 1),
    Pos( 0,-1,-1),
    Pos( 0,-1, 0),
    Pos( 0,-1, 1),
    Pos( 0, 0,-1),
    Pos( 0, 0, 1),
    Pos( 0, 1,-1),
    Pos( 0, 1, 0),
    Pos( 0, 1, 1),
    Pos( 1,-1,-1),
    Pos( 1,-1, 0),
    Pos( 1,-1, 1),
    Pos( 1, 0,-1),
    Pos( 1, 0, 0),
    Pos( 1, 0, 1),
    Pos( 1, 1,-1),
    Pos( 1, 1, 0),
    Pos( 1, 1, 1),
  };
  const int N = sizeof(delta) / sizeof(*delta);

  // find neighbours of somePos
  double cube_size = 0.5; 
  Pos somePos(0.5, 0.5, 0.5);

  std::vector<Pos> neighbours(N, somePos);  
  translate(neighbours.begin(), neighbours.end(), delta, cube_size);

  // print neighbours
  std::copy(neighbours.begin(), neighbours.end(), 
        std::ostream_iterator<Pos>(std::cout, "\n"));
  std::cout << std::endl;

  return 0;
}
J.F. Sebastian
Instead of copy-pasting the Pos()-parameters, you should generate them with a nested loop.
Svante
@Harleqin: the above code is an intermediate step towards machine-generated code without any loops at all. I don't know what are diater's concrete data structures, tradeofs; therefore I didn't push it further.
J.F. Sebastian
A: 
for(int i = 0; i < 27, i++)
{
   if(i == 13) continue;
   int dx = i%3 -1;
   int dy = (i/3)%3 -1;
   int dz = i/9 - 1;

   process(x+dx,y+dy,z+dz);
}
BCS