VoxelLine.cpp
Go to the documentation of this file.
1 #include "VoxelLine.h"
2 
4 
5 
6 namespace visionx
7 {
8 
9  const Eigen::IOFormat VoxelLine::iof{3, 0, " ", " ", "", "", "[", "]"};
10 
11 
12  VoxelLine::VoxelLine() : _finished(true)
13  {}
14 
16  const Eigen::Vector3i& start, const Eigen::Vector3i& end,
17  bool includeStart, bool includeEnd) :
18  start(start), end(end), includeStart(includeStart), includeEnd(includeEnd)
19  {
20  init();
21  }
22 
23 
24  void 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 VoxelLine::advance()
56  {
57  if (_next(x) != end(x))
58  {
59  // Advance on the line.
60  _next(x) += step(x);
61 
62  if (py >= 0)
63  {
64  _next(y) += step(y);
65  py -= 2 * delta(x);
66  }
67  if (pz >= 0)
68  {
69  _next(z) += step(z);
70  pz -= 2 * delta(x);
71  }
72  py += 2 * delta(y);
73  pz += 2 * delta(z);
74  }
75  else
76  {
77  // The next will be end, after that the line is finished.
78  _finished = true;
79  }
80 
81  if (_next(x) == end(x) && !includeEnd)
82  {
83  // The next would be end, but that shall be excluded.
84  _finished = true;
85  }
86  }
87 
88 
89  bool VoxelLine::finished() const
90  {
91  return _finished;
92  }
93 
94  Eigen::Vector3i VoxelLine::next()
95  {
96  if (_finished)
97  {
98  throw std::logic_error("No more voxels on the line. "
99  "Check VoxelLine::finished() before calling VoxelLine::next().");
100  }
101 
102  Eigen::Vector3i next = _next;
103  advance();
104  return next;
105  }
106 
107 
108  std::vector<Eigen::Vector3i> VoxelLine::getLineVoxels(
109  const Eigen::Vector3i& start, const Eigen::Vector3i& end,
110  bool includeStart, bool includeEnd)
111  {
112  VoxelLine line(start, end, includeStart, includeEnd);
113  std::vector<Eigen::Vector3i> points;
114 
115  while (!line.finished())
116  {
117  points.push_back(line.next());
118  }
119 
120  return points;
121  }
122 
123 }
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
visionx::VoxelLine
A line of voxels, from start voxel to an end voxel.
Definition: VoxelLine.h:27
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:108
visionx::VoxelLine::next
Eigen::Vector3i next()
Get the next voxel.
Definition: VoxelLine.cpp:94
visionx::VoxelLine::VoxelLine
VoxelLine()
Construct an empty voxel line.
Definition: VoxelLine.cpp:12
ExpressionException.h
VoxelLine.h
visionx::VoxelLine::finished
bool finished() const
Indicate whether there are more voxels on the line.
Definition: VoxelLine.cpp:89