在 3d 空间中创建邻居节点的循环

Posted

技术标签:

【中文标题】在 3d 空间中创建邻居节点的循环【英文标题】:A loop to create neighbor nodes in 3d space 【发布时间】:2008-11-28 23:20:57 【问题描述】:

我想在 3-d 空间中创建一个立方体素节点的 26 个邻居。输入是节点的 x,y,z 位置和立方体边的大小。我正在尝试使用 for 循环来执行此操作,但尚未管理。我是编程新手,请帮助我。

【问题讨论】:

【参考方案1】:
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
      
    
  

【讨论】:

您可能需要在边缘情况下进行一些边界检查,但您肯定回答了这个问题。 +1 修正错字:++z,y,x 应分别为 ++dz,dy,dx。 三个循环的末尾必须分别有“++dz”、“++dy”和“++dx”;你不想自己改变 x,y,z。【参考方案2】:

这是一个没有嵌套循环的变体。我尝试使用类似于your question 的符号。

// 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;

【讨论】:

您应该使用嵌套循环生成它们,而不是复制粘贴 Pos() 参数。 @Harleqin:上面的代码是机器生成代码的中间步骤,完全没有任何循环。我不知道 diater 的具体数据结构是什么,权衡取舍;因此我没有进一步推动它。【参考方案3】:
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);

【讨论】:

以上是关于在 3d 空间中创建邻居节点的循环的主要内容,如果未能解决你的问题,请参考以下文章

我可以优化具有 3 个 for 循环和 4 个 if 的代码吗?

点的第 k 个最近邻居的空间查询

使用 ggmap、geom_point 和循环映射 long-lat 数据集的最近邻居

在桌面打开网上邻居点整个网络,在点开Microsoft windows network

爬山算法

三天没有写题了,罪过!--Hash Table Start