VoxelLine.cpp
Go to the documentation of this file.
1#include "VoxelLine.h"
2
4
5namespace 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
VoxelLine()
Construct an empty voxel line.
Definition VoxelLine.cpp:10
Eigen::Vector3i next()
Get the next voxel.
Definition VoxelLine.cpp:96
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.
bool finished() const
Indicate whether there are more voxels on the line.
Definition VoxelLine.cpp:90
This file offers overloads of toIce() and fromIce() functions for STL container types.
ArmarX headers.