Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "cartographer/mapping/internal/2d/ray_to_pixel_mask.h"
00018
00019 #include "Eigen/Dense"
00020
00021 namespace cartographer {
00022 namespace mapping {
00023 namespace {
00024
00025 bool isEqual(const Eigen::Array2i& lhs, const Eigen::Array2i& rhs) {
00026 return ((lhs - rhs).matrix().lpNorm<1>() == 0);
00027 }
00028 }
00029
00030
00031
00032
00033
00034 std::vector<Eigen::Array2i> RayToPixelMask(const Eigen::Array2i& scaled_begin,
00035 const Eigen::Array2i& scaled_end,
00036 int subpixel_scale) {
00037
00038
00039 if (scaled_begin.x() > scaled_end.x()) {
00040 return RayToPixelMask(scaled_end, scaled_begin, subpixel_scale);
00041 }
00042
00043 CHECK_GE(scaled_begin.x(), 0);
00044 CHECK_GE(scaled_begin.y(), 0);
00045 CHECK_GE(scaled_end.y(), 0);
00046 std::vector<Eigen::Array2i> pixel_mask;
00047
00048
00049 if (scaled_begin.x() / subpixel_scale == scaled_end.x() / subpixel_scale) {
00050 Eigen::Array2i current(
00051 scaled_begin.x() / subpixel_scale,
00052 std::min(scaled_begin.y(), scaled_end.y()) / subpixel_scale);
00053 pixel_mask.push_back(current);
00054 const int end_y =
00055 std::max(scaled_begin.y(), scaled_end.y()) / subpixel_scale;
00056 for (; current.y() <= end_y; ++current.y()) {
00057 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00058 }
00059 return pixel_mask;
00060 }
00061
00062 const int64 dx = scaled_end.x() - scaled_begin.x();
00063 const int64 dy = scaled_end.y() - scaled_begin.y();
00064 const int64 denominator = 2 * subpixel_scale * dx;
00065
00066
00067 Eigen::Array2i current = scaled_begin / subpixel_scale;
00068 pixel_mask.push_back(current);
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 int64 sub_y = (2 * (scaled_begin.y() % subpixel_scale) + 1) * dx;
00083
00084
00085
00086 const int first_pixel =
00087 2 * subpixel_scale - 2 * (scaled_begin.x() % subpixel_scale) - 1;
00088
00089 const int last_pixel = 2 * (scaled_end.x() % subpixel_scale) + 1;
00090
00091
00092 const int end_x = std::max(scaled_begin.x(), scaled_end.x()) / subpixel_scale;
00093
00094
00095 sub_y += dy * first_pixel;
00096 if (dy > 0) {
00097 while (true) {
00098 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00099 while (sub_y > denominator) {
00100 sub_y -= denominator;
00101 ++current.y();
00102 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00103 }
00104 ++current.x();
00105 if (sub_y == denominator) {
00106 sub_y -= denominator;
00107 ++current.y();
00108 }
00109 if (current.x() == end_x) {
00110 break;
00111 }
00112
00113 sub_y += dy * 2 * subpixel_scale;
00114 }
00115
00116 sub_y += dy * last_pixel;
00117 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00118 while (sub_y > denominator) {
00119 sub_y -= denominator;
00120 ++current.y();
00121 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00122 }
00123 CHECK_NE(sub_y, denominator);
00124 CHECK_EQ(current.y(), scaled_end.y() / subpixel_scale);
00125 return pixel_mask;
00126 }
00127
00128
00129 while (true) {
00130 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00131 while (sub_y < 0) {
00132 sub_y += denominator;
00133 --current.y();
00134 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00135 }
00136 ++current.x();
00137 if (sub_y == 0) {
00138 sub_y += denominator;
00139 --current.y();
00140 }
00141 if (current.x() == end_x) {
00142 break;
00143 }
00144 sub_y += dy * 2 * subpixel_scale;
00145 }
00146 sub_y += dy * last_pixel;
00147 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00148 while (sub_y < 0) {
00149 sub_y += denominator;
00150 --current.y();
00151 if (!isEqual(pixel_mask.back(), current)) pixel_mask.push_back(current);
00152 }
00153 CHECK_NE(sub_y, 0);
00154 CHECK_EQ(current.y(), scaled_end.y() / subpixel_scale);
00155 return pixel_mask;
00156 }
00157
00158 }
00159 }