VoxelLine.cpp
Go to the documentation of this file.
1 #include "VoxelLine.h"
2 
4 
5 namespace visionx
6 {
7 
8  const Eigen::IOFormat VoxelLine::iof{3, 0, " ", " ", "", "", "[", "]"};
9 
10  VoxelLine::VoxelLine() : _finished(true)
11  {
12  }
13 
14  VoxelLine::VoxelLine(const Eigen::Vector3i& start,
15  const Eigen::Vector3i& end,
16  bool includeStart,
17  bool includeEnd) :
18  start(start), end(end), includeStart(includeStart), includeEnd(includeEnd)
19  {
20  init();
21  }
22 
23  void
24  VoxelLine::init()
25  {
26  delta = end - start;
27 
28  // Choose direction.
29  for (Index i = 0; i < step.size(); ++i)
30  {
31  step(i) = delta(i) >= 0 ? 1 : -1;
32  }
33 
34  delta = delta.cwiseAbs();
35 
36  // Choose the driving and non-driving axes.
37  delta.maxCoeff(&x);
38 
39  y = x != 0 ? 0 : 1; // y = 0, except for x = 0, then y = 1 (and z = 2)
40  z = x != 2 ? 2 : 1; // z = 2, except for x = 2, then z = 1 (and y = 0)
41 
42  py = 2 * delta(y) - delta(x);
43  pz = 2 * delta(z) - delta(x);
44 
45  _finished = false;
46  _next = start;
47 
48  // Skip start if excluded, but not if it is equal to end and end shall be included.
49  if (!includeStart && !(includeEnd && start == end))
50  {
51  advance();
52  }
53  }
54 
55  void
56  VoxelLine::advance()
57  {
58  if (_next(x) != end(x))
59  {
60  // Advance on the line.
61  _next(x) += step(x);
62 
63  if (py >= 0)
64  {
65  _next(y) += step(y);
66  py -= 2 * delta(x);
67  }
68  if (pz >= 0)
69  {
70  _next(z) += step(z);
71  pz -= 2 * delta(x);
72  }
73  py += 2 * delta(y);
74  pz += 2 * delta(z);
75  }
76  else
77  {
78  // The next will be end, after that the line is finished.
79  _finished = true;
80  }
81 
82  if (_next(x) == end(x) && !includeEnd)
83  {
84  // The next would be end, but that shall be excluded.
85  _finished = true;
86  }
87  }
88 
89  bool
91  {
92  return _finished;
93  }
94 
95  Eigen::Vector3i
97  {
98  if (_finished)
99  {
100  throw std::logic_error("No more voxels on the line. "
101  "Check VoxelLine::finished() before calling VoxelLine::next().");
102  }
103 
104  Eigen::Vector3i next = _next;
105  advance();
106  return next;
107  }
108 
109  std::vector<Eigen::Vector3i>
110  VoxelLine::getLineVoxels(const Eigen::Vector3i& start,
111  const Eigen::Vector3i& end,
112  bool includeStart,
113  bool includeEnd)
114  {
115  VoxelLine line(start, end, includeStart, includeEnd);
116  std::vector<Eigen::Vector3i> points;
117 
118  while (!line.finished())
119  {
120  points.push_back(line.next());
121  }
122 
123  return points;
124  }
125 
126 } // namespace visionx
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
visionx::VoxelLine
A line of voxels, from start voxel to an end voxel.
Definition: VoxelLine.h:26
visionx::VoxelLine::getLineVoxels
static std::vector< Eigen::Vector3i > getLineVoxels(const Eigen::Vector3i &start, const Eigen::Vector3i &end, bool includeStart=true, bool includeEnd=true)
Get the voxels indices of the line from start to end.
Definition: VoxelLine.cpp:110
visionx::VoxelLine::next
Eigen::Vector3i next()
Get the next voxel.
Definition: VoxelLine.cpp:96
visionx::VoxelLine::VoxelLine
VoxelLine()
Construct an empty voxel line.
Definition: VoxelLine.cpp:10
ExpressionException.h
VoxelLine.h
visionx::VoxelLine::finished
bool finished() const
Indicate whether there are more voxels on the line.
Definition: VoxelLine.cpp:90