37 #include "PolyWorld.h"
42 #include <yaml-cpp/yaml.h>
52 int turn(Point p, Point q, Point r)
54 const double orn = (q.first - p.first) * (r.second - p.second) - (r.first - p.first) * (q.second - p.second);
64 double sqrDistance(Point p1, Point p2)
66 const double dx = p2.first - p1.first;
67 const double dy = p2.second - p1.second;
68 return dx * dx + dy * dy;
73 bool cmpDouble(
double a,
double b,
const double eps)
75 return fabs(a - b) < eps;
78 bool equalPoints(Point p0, Point p1)
80 return cmpDouble(p0.first, p1.first) && cmpDouble(p0.second, p1.second);
83 ConvexPolygon::ConvexPolygon(
const std::vector<Point> &coords)
85 assert(coords.size() >= 3);
90 for (
size_t i = 1; i < coords.size(); ++i)
92 if (coords[i].first < coords[left_idx].first)
94 else if (coords[i].first == coords[left_idx].first)
96 if (coords[i].second < coords[left_idx].second)
102 coordinates_.push_back(coords[left_idx]);
103 for (
size_t i = 0; i < coordinates_.size(); ++i)
105 const Point p = coordinates_[i];
108 for (
size_t j = 0; j < coords.size(); ++j)
110 const int t = turn(p, q, coords[j]);
111 if (t == -1 || (t == 0 && sqrDistance(p, coords[j]) > sqrDistance(p, q)))
117 if (!equalPoints(q, coordinates_[0]))
118 coordinates_.push_back(q);
127 bool ConvexPolygon::inside(Point point)
const
131 for (i = 0, j = coordinates_.size() - 1; i < coordinates_.size(); j = i++)
133 if (((coordinates_[i].second >
point.second) != (coordinates_[j].second >
point.second)) &&
134 (
point.first < (coordinates_[j].first - coordinates_[i].first) * (
point.second - coordinates_[i].second) /
135 (coordinates_[j].second - coordinates_[i].second) +
136 coordinates_[i].first))
144 PolyWorld::PolyWorld(
const std::string &worldName,
const std::pair<double, double> &xBounds,
145 const std::pair<double, double> &yBounds)
146 : worldName_(worldName)
148 assert(xBounds.first < xBounds.second);
149 assert(yBounds.first < yBounds.second);
151 bounds_[0] = xBounds;
152 bounds_[1] = yBounds;
155 const std::string &PolyWorld::worldName()
const
160 std::pair<double, double> PolyWorld::xBounds()
const
162 assert(bounds_.size() > 0);
166 std::pair<double, double> PolyWorld::yBounds()
const
168 assert(bounds_.size() > 1);
172 size_t PolyWorld::numObstacles()
const
174 return obstacles_.size();
177 const std::vector<ConvexPolygon> &PolyWorld::obstacles()
const
184 assert(i < obstacles_.size());
185 return obstacles_[i];
190 obstacles_.push_back(polygon);
193 bool PolyWorld::outOfBounds(
const Point p)
const
195 return p.first <= bounds_[0].first || p.first >= bounds_[0].second || p.second <= bounds_[1].first ||
196 p.second >= bounds_[1].second;
199 bool PolyWorld::pointCollisionFree(
const Point p)
const
202 for (
size_t i = 0; i < obstacles_.size() && valid; ++i)
204 valid = !(obstacles_[i].inside(p));
209 void PolyWorld::writeWorld(
const char *filename)
const
215 OMPL_ERROR(
"Failed to open %s for writing", filename);
220 out << YAML::BeginMap;
221 out << YAML::Key <<
"name";
222 out << YAML::Value << worldName_;
224 out << YAML::Key <<
"bounds";
225 out << YAML::BeginMap;
226 out << YAML::Key <<
"x";
227 out << YAML::BeginMap;
228 out << YAML::Key <<
"lower";
229 out << YAML::Value << bounds_[0].first;
230 out << YAML::Key <<
"upper";
231 out << YAML::Value << bounds_[0].second;
233 out << YAML::Key <<
"y";
234 out << YAML::BeginMap;
235 out << YAML::Key <<
"lower";
236 out << YAML::Value << bounds_[1].first;
237 out << YAML::Key <<
"upper";
238 out << YAML::Value << bounds_[1].second;
242 out << YAML::Key <<
"obstacles";
243 out << YAML::BeginSeq;
245 for (
size_t i = 0; i < obstacles_.size(); ++i)
249 out << YAML::BeginMap;
251 out << YAML::BeginSeq;
252 for (
size_t j = 0; j < polygon.numPoints(); ++j)
254 Point p = polygon[j];
256 out << YAML::BeginMap;
257 out << YAML::Key <<
"vertex";
259 std::stringstream str;
260 str <<
"(" << p.first <<
"," << p.second <<
")";
261 out << YAML::Value << str.str();