polygon_utils.h
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     //          std::cerr << "pts[" << i << "]: " << "(" << pts[i].x << "," << pts[i].y << ") " << result.back() << " ";
00053     //          std::cerr << "next is " << "(" << pts[(i+1)%pts.size()].x << " " << pts[(i+1)%pts.size()].y << ")\n";
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 // inline is necessary here because of linker error for multiple definition.
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 } // namespace lama_common
00189 
00190 #endif // LAMA_COMMON_POLYGON_UTILS_H


lama_common
Author(s): Gaël Ecorchard , Karel Košnar , Vojtěch Vonásek
autogenerated on Thu Jun 6 2019 22:02:03