Go to the documentation of this file.00001 #pragma once
00002 #ifndef LAMA_COMMON_POLYGON_UTILS_H
00003 #define LAMA_COMMON_POLYGON_UTILS_H
00004
00005 #include <vector>
00006 #include <numeric>
00007
00008 #include <geometry_msgs/Point32.h>
00009 #include <geometry_msgs/Polygon.h>
00010 #include <sensor_msgs/LaserScan.h>
00011
00012 #include <lama_common/point.h>
00013 #include <lama_common/is_sorted.h>
00014
00015 namespace lama_common
00016 {
00017
00018 using std::vector;
00019 using geometry_msgs::Point32;
00020
00023 template<typename T>
00024 double getLength(const vector<T> &pts)
00025 {
00026 double length = 0;
00027 for(size_t i = 0; i < pts.size() - 1; i++)
00028 {
00029 length += pointDistance2(pts[i], pts[i+1]);
00030 }
00031 if (pts.size() > 2)
00032 {
00033 length += pointDistance2(pts.front(), pts.back());
00034 }
00035 return length;
00036 }
00037
00043 template<typename T>
00044 vector<double> getLengths(const vector<T> &pts)
00045 {
00046 vector<double> result;
00047 result.reserve(pts.size());
00048
00049 for (size_t i = 0; i < pts.size(); i++)
00050 {
00051 result.push_back(pointDistance2(pts[i], pts[(i + 1) % pts.size()]));
00052
00053
00054 }
00055 return result;
00056 }
00057
00058
00068 template<typename T>
00069 vector<T> resamplePolygon(const vector<T>& polygon, unsigned int sample_count, double& delta)
00070 {
00071 vector<double> lengths(getLengths(polygon));
00072 const double polygonLength = std::accumulate(lengths.begin(), lengths.end(), 0.0);
00073 const double dl = polygonLength / (double)sample_count;
00074 delta = dl;
00075
00076 vector<T> result;
00077 result.reserve(sample_count);
00078
00079 int last = 0;
00080 const int size = polygon.size();
00081 double alength = 0;
00082 double tmpl;
00083 int lnext;
00084 for (double l = 0; l < polygonLength; l += dl)
00085 {
00086 while (last < size && (alength + lengths[last]) < l)
00087 {
00088 alength += lengths[last];
00089 last++;
00090 }
00091 if (last == size)
00092 {
00093 break;
00094 }
00095 lnext = (last == (size - 1)) ? 0 : (last + 1);
00096 tmpl = l - alength;
00097 result.push_back(T(
00098 polygon[last].x * (1 - tmpl / lengths[last]) + polygon[lnext].x * (tmpl / lengths[last]),
00099 polygon[last].y * (1 - tmpl / lengths[last]) + polygon[lnext].y * (tmpl / lengths[last])));
00100 }
00101
00102 return result;
00103 }
00104
00113
00114 template <>
00115 inline vector<Point32> resamplePolygon<Point32>(const vector<Point32>& polygon, unsigned int sample_count, double& delta)
00116 {
00117 vector<Point2> points;
00118 points.reserve(polygon.size());
00119 for (size_t i = 0; i < polygon.size(); ++i)
00120 {
00121 points.push_back(Point2(polygon[i]));
00122 }
00123
00124 vector<Point2> resampledPoints = resamplePolygon(points, sample_count, delta);
00125
00126 vector<Point32> resampledGPoints;
00127 resampledGPoints.reserve(resampledPoints.size());
00128 for (size_t i = 0; i < resampledPoints.size(); ++i)
00129 {
00130 Point32 gpoint;
00131 gpoint.x = resampledPoints[i].x;
00132 gpoint.y = resampledPoints[i].y;
00133 resampledGPoints.push_back(gpoint);
00134 }
00135
00136 return resampledGPoints;
00137 }
00138
00143 template <typename T>
00144 vector<T> scanToPolygon(const sensor_msgs::LaserScan& scan)
00145 {
00146 vector<T> polygon;
00147 polygon.reserve(scan.ranges.size());
00148 double angle = scan.angle_min;
00149 for (size_t i = 0; i < scan.ranges.size(); ++i)
00150 {
00151 const double r = scan.ranges[i];
00152 polygon.push_back(T(r * std::cos(angle), r * std::sin(angle)));
00153 angle += scan.angle_increment;
00154 }
00155 return polygon;
00156 }
00157
00161 inline geometry_msgs::Polygon scanToPolygon(const sensor_msgs::LaserScan& scan)
00162 {
00163 geometry_msgs::Polygon polygon;
00164 polygon.points.reserve(scan.ranges.size());
00165 double angle = scan.angle_min;
00166 for (size_t i = 0; i < scan.ranges.size(); ++i)
00167 {
00168 const double r = scan.ranges[i];
00169 Point32 point;
00170 point.x = r * std::cos(angle);
00171 point.y = r * std::sin(angle);
00172 polygon.points.push_back(point);
00173 angle += scan.angle_increment;
00174 }
00175 return polygon;
00176 }
00177
00178 void centerPolygon(geometry_msgs::Polygon& polygon);
00179 void centerPolygon(geometry_msgs::Polygon& polygon, double& dx, double& dy);
00180 geometry_msgs::Polygon centeredPolygon(const geometry_msgs::Polygon& polygon);
00181 geometry_msgs::Polygon centeredPolygon(const geometry_msgs::Polygon& polygon, double& dx, double& dy);
00182
00183 bool normalizePolygon(geometry_msgs::Polygon& poly);
00184 geometry_msgs::Polygon normalizedPolygon(const geometry_msgs::Polygon& poly, bool& normalized);
00185
00186 bool isClosed(const geometry_msgs::Polygon& poly, double max_frontier_width);
00187
00188 }
00189
00190 #endif // LAMA_COMMON_POLYGON_UTILS_H