简介
本文的代码部分都比较简单容易
Boost Geometry 是 Boost C++ 库集合的一部分,定义了用于解决几何问题的概念、工具和算法。这个库比较常用,很多现成的函数都很实用且简单,本文记录一些常用的函数和操作,重复的功能以后还会用到,到时回来查看比阅读文档方便。
Polygon操作经常用于机器人行业的感知系统中,特别是用于定义安全区域和障碍物边界框等任务。一些常见的应用包括:
- 计算障碍物边界框与安全区域之间的重叠比例,以确定危险级别。
- 验证障碍物是否进入自动驾驶车辆的危险区域。
- 确定一些激光雷达点是否位于指定区域内。
应用实现
需求:
- 生成随机多边形:创建两个随机多边形。
- 有效性检查和面积计算:验证多边形的有效性并计算它们的面积。
- 相交检测:确定两个多边形是否相交,并在相交时计算交叉多边形。
- 点包含检查:检查指定点是否位于交叉多边形内。
代码:
#include <iostream>
#include <string>
#include <deque>
#include <vector> // To contain points
#include <random> // Random generate points
#include <stdexcept>// for std::runtime_error
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp> // Points, lines, polygons, etc.
#include <boost/geometry/geometries/point_xy.hpp> // 2 D point point_xy
#include <boost/geometry/geometries/polygon.hpp> // Polygon geometry, sequence of points for a closed loopnamespace bg = boost::geometry;
// Create type aliases
using Point = bg::model::d2::point_xy<double>;
using Points = std::vector<Point>;
using Polygon = bg::model::polygon<Point>;Polygon getOverlappingPolygon(const Polygon& polygon_1, const Polygon& polygon_2)
{std::deque<Polygon> overlapping_polygon; // The overlapping polygon number can more than onebg::intersection(polygon_1, polygon_2, overlapping_polygon);return overlapping_polygon.front();
}bool checkPolygonIntersection(const Polygon& polygon_1, const Polygon& polygon_2)
{ return bg::covered_by(polygon_1, polygon_2) || bg::overlaps(polygon_1, polygon_2);
}void printPoints(const Points& points)
{std::cout << "Generated Points:" << std::endl;for (const auto& point : points) {std::cout << "(" << bg::get<0>(point) << ", " << bg::get<1>(point) << ")" << std::endl;}
}Points generateRandomPoints(int num_points, double min_x, double max_x, double min_y, double max_y)
{std::random_device rd;std::mt19937 gen(rd());std::uniform_real_distribution<double> dist_x(min_x, max_x);std::uniform_real_distribution<double> dist_y(min_y, max_y);Points points;for (int i = 0; i < num_points; ++i){points.push_back(Point(dist_x(gen), dist_y(gen)));}points.push_back(points.front()); // To close the loop, otherwise polygon is invalidreturn points;
}Polygon generatePolygon(const Points& points)
{Polygon polygon;bg::assign_points(polygon, points);return polygon;
}void printPolygon(const Polygon polygon, const std::string& prefix = "")
{std::cout << "Polygon " << prefix << " points are: ";for (const auto& point : polygon.outer()) {std::cout << "(" << boost::geometry::get<0>(point) << ", " << boost::geometry::get<1>(point) << ") ";}std::cout << "\t Area is: " << bg::area(polygon) << std::endl;
}Polygon generateRandomPolygon(int num_points = 4, double min_x = 0, double max_x = 4, double min_y = 0, double max_y = 4)
{int max_attempts = 10;while(max_attempts > 0){Points points = generateRandomPoints(num_points, min_x, max_x, min_y, max_y);Polygon polygon = generatePolygon(points);if (bg::is_valid(polygon)) // Check if the polygon is valid{return polygon;}std::cout << "Polygon is invalid, retrying..." << std::endl;max_attempts--;}throw std::runtime_error("Failed to generate a valid polygon after maximum attempts.");
}int main()
{Polygon polygon_1 = generateRandomPolygon();printPolygon(polygon_1, "1");Polygon polygon_2 = generateRandomPolygon();printPolygon(polygon_2, "2");// Check intersectionif (checkPolygonIntersection(polygon_1, polygon_2)){// Print the intersection polygon points and areaPolygon intersect_polygon = getOverlappingPolygon(polygon_1, polygon_2);printPolygon(intersect_polygon, "intersect");// Check if the origin point inside the polygonPoint origin = {0, 0};if (bg::within(origin, polygon_1)){std::cout << "origin is inside the polygon" << std::endl;}else{std::cout << "origin is outside the polygon" << std::endl;}}else{std::cout << "Two polygons are not intersected" << std::endl;}
}
一个样例输出:
Polygon is invalid, retrying...
Polygon is invalid, retrying...
Polygon 1 points are: (1.05432, 2.2592) (1.5928, 3.05599) (2.93741, 2.09024) (1.47085, 0.798034) (1.05432, 2.2592) Area is: 2.13627
Polygon is invalid, retrying...
Polygon is invalid, retrying...
Polygon is invalid, retrying...
Polygon 2 points are: (1.97136, 2.36949) (2.81913, 0.603898) (1.81515, 1.29083) (0.327355, 3.53608) (1.97136, 2.36949) Area is: 1.5729
Polygon intersect points are: (1.11448, 2.34822) (1.40193, 2.77356) (1.97136, 2.36949) (2.35279, 1.57512) (1.93617, 1.20803) (1.81515, 1.29083) (1.11448, 2.34822) Area is: 0.946869
origin is outside the polygon