12 #ifndef INCLUDED_cgutil_hpp_ 13 #define INCLUDED_cgutil_hpp_ 23 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> 24 #include <CGAL/Partition_is_valid_traits_2.h> 25 #include <CGAL/Partition_traits_2.h> 26 #include <CGAL/partition_2.h> 27 #include <CGAL/point_generators_2.h> 28 #include <CGAL/polygon_function_objects.h> 29 #include <CGAL/random_polygon_2.h> 35 #include <geometry_msgs/Point.h> 42 using K = CGAL::Exact_predicates_inexact_constructions_kernel;
43 using Traits = CGAL::Partition_traits_2<K>;
75 const geometry_msgs::Point& p3)
77 return p1.x * (p2.y - p3.y) - p1.y * (p2.x - p3.x) + (p2.x * p3.y - p2.y * p3.x);
87 bool operator==(
const geometry_msgs::Point& p1,
const geometry_msgs::Point& p2)
90 p1.x == p2.x || std::abs(p1.x - p2.x) < std::abs(std::min(p1.x, p2.x)) * std::numeric_limits<double>::epsilon();
92 p1.y == p2.y || std::abs(p1.y - p2.y) < std::abs(std::min(p1.y, p2.y)) * std::numeric_limits<double>::epsilon();
94 p1.z == p2.z || std::abs(p1.z - p2.z) < std::abs(std::min(p1.z, p2.z)) * std::numeric_limits<double>::epsilon();
105 bool operator!=(
const geometry_msgs::Point& p1,
const geometry_msgs::Point& p2)
121 if (vec.empty() ==
true)
126 for (
int i = 0; i < vec.size(); ++i)
130 edge.at(0) = vec.at(i);
132 if (i < vec.size() - 1)
135 edge.at(1) = vec.at(i + 1);
140 edge.at(1) = vec.at(0);
147 edgeVector.push_back(edge);
160 return std::sqrt(std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2));
171 const geometry_msgs::Point& p3)
177 double lenE1, lenE2, lenE3;
184 cosineP1 = (std::pow(lenE1, 2) + std::pow(lenE3, 2) - std::pow(lenE2, 2)) / (2 * lenE1 * lenE3);
188 if (std::isnan(cosineP1) != 0)
193 return std::acos(cosineP1);
204 geometry_msgs::Point p3;
219 geometry_msgs::Point pointA, pointB;
220 pointA = edge.front();
221 pointB = edge.back();
226 double lenEdgeA, lenEdgeB;
237 double distance = alpha < M_PI_2 ? std::sin(alpha) * lenEdgeB : std::sin(beta) * lenEdgeA;
253 if (points.empty() or points.size() < 3)
259 for (
size_t i = 0; i < points.size() - 1; ++i)
261 if (points.at(i).x == points.at(i + 1).x and points.at(i).y == points.at(i + 1).y)
263 points.erase(points.begin() + i);
267 if (points.size() < 3)
273 std::stable_sort(points.begin(), points.end(),
274 [](
const geometry_msgs::Point& p1,
const geometry_msgs::Point& p2) {
return p1.y < p2.y; });
277 geometry_msgs::Point pointMinY = points.front();
278 points.erase(points.begin());
283 std::stable_sort(points.begin(), points.end(), [&](
const geometry_msgs::Point& p1,
const geometry_msgs::Point& p2) {
288 convexHull.push_back(pointMinY);
291 convexHull.push_back(points.front());
292 points.erase(points.begin());
294 for (
const auto& point : points)
296 for (std::size_t i = convexHull.size() - 1; i > 1; --i)
303 convexHull.pop_back();
305 convexHull.push_back(point);
308 geometry_msgs::Point origin;
311 std::stable_sort(convexHull.begin(), convexHull.end(),
312 [&](
const geometry_msgs::Point& p1,
const geometry_msgs::Point& p2) {
337 geometry_msgs::Point p1, p2, p3, p4;
346 catch (std::out_of_range& ex)
348 ROS_ERROR(
"%s", ex.what());
352 bool condA = ((p1.x - p2.x) * (p3.y - p1.y) + (p1.y - p2.y) * (p1.x - p3.x)) *
353 ((p1.x - p2.x) * (p4.y - p1.y) + (p1.y - p2.y) * (p1.x - p4.x)) <
355 bool condB = ((p3.x - p4.x) * (p1.y - p3.y) + (p3.y - p4.y) * (p3.x - p1.x)) *
356 ((p3.x - p4.x) * (p2.y - p3.y) + (p3.y - p4.y) * (p3.x - p2.x)) <
377 for (
const auto& segment1 : vec1)
379 for (
const auto& segment2 : vec2)
400 geometry_msgs::Point p1, p2, p3, p4;
409 catch (
const std::out_of_range& ex)
411 ROS_ERROR(
"%s", ex.what());
414 double xi, eta, delta;
415 xi = (p4.y - p3.y) * (p4.x - p1.x) - (p4.x - p3.x) * (p4.y - p1.y);
416 eta = -(p2.y - p1.y) * (p4.x - p1.x) + (p2.x - p1.x) * (p4.y - p1.y);
417 delta = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
423 geometry_msgs::Point intersection;
425 intersection.x = p1.x + lambda * (p2.x - p1.x);
426 intersection.y = p1.y + lambda * (p2.y - p1.y);
439 std::array<double, 4> rotationMatrix;
440 rotationMatrix.at(0) = std::cos(angle_rad);
441 rotationMatrix.at(1) = -std::sin(angle_rad);
442 rotationMatrix.at(2) = std::sin(angle_rad);
443 rotationMatrix.at(3) = std::cos(angle_rad);
447 for (
const auto& point : points)
449 geometry_msgs::Point pt;
450 pt.x = rotationMatrix.at(0) * point.x + rotationMatrix.at(1) * point.y;
451 pt.y = rotationMatrix.at(2) * point.x + rotationMatrix.at(3) * point.y;
452 rotatedPoints.push_back(pt);
454 return rotatedPoints;
470 std::vector<PointVector> decomposedPolygons;
474 for (
const auto& vertex : polygon)
476 cgalPolygon.push_back(
Point_2(vertex.x, vertex.y));
485 CGAL::optimal_convex_partition_2(cgalPolygon.vertices_begin(), cgalPolygon.vertices_end(),
486 std::back_inserter(partialCGALPolygons), partitionTraits);
489 for (
const auto& partialCGALPolygon : partialCGALPolygons)
492 for (
auto itr = partialCGALPolygon.vertices_begin(); itr != partialCGALPolygon.vertices_end(); ++itr)
494 geometry_msgs::Point pt;
497 partialPolygon.push_back(pt);
499 decomposedPolygons.push_back(partialPolygon);
502 return decomposedPolygons;
double calculateVertexAngle(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2, const geometry_msgs::Point &p3)
Calculates angle between segment p1p2 and p1p3.
std::array< geometry_msgs::Point, 2 > LineSegment
double calculateHorizontalAngle(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Calculates angle between segment p1p2 and horizontal line.
CGAL::Partition_traits_2< K > Traits
bool operator!=(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Check equality of two points.
LineSegmentVector generateEdgeVector(const PointVector &vec, bool isClosed)
Generate Vector of line segment from given PointVector.
std::vector< LineSegment > LineSegmentVector
double calculateSignedArea(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2, const geometry_msgs::Point &p3)
Calculates signed area of given triangle.
double calculateDistance(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Calculates distance between given two points.
PointVector rotatePoints(const PointVector &points, double angle_rad)
Rotate points by given angle around the origin.
bool isConvex(PointVector points)
Checks if given polygon is convex or not.
std::vector< geometry_msgs::Point > PointVector
PointVector computeConvexHull(PointVector points)
Returns convex hull of given points.
geometry_msgs::Point localizeIntersection(const LineSegment &edge1, const LineSegment &edge2)
Find the location where given edges intersect each other.
CGAL::Exact_predicates_inexact_constructions_kernel K
std::vector< PointVector > decomposePolygon(const PointVector &polygon)
Decompose given polygon.
bool hasIntersection(const LineSegment &edge1, const LineSegment &edge2)
Checks if given edges intersect each other.
bool operator==(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Check equality of two points.
std::list< Polygon_2 > Polygon_list
Traits::Polygon_2 Polygon_2
Polygon_2::Vertex_const_iterator Vertex_iterator