【编程】Boost::geometry Polygon 常用应用代码记录(C++)

发布于:2024-04-08 ⋅ 阅读:(259) ⋅ 点赞:(0)

简介

本文的代码部分都比较简单容易

Boost Geometry 是 Boost C++ 库集合的一部分,定义了用于解决几何问题的概念、工具和算法。这个库比较常用,很多现成的函数都很实用且简单,本文记录一些常用的函数和操作,重复的功能以后还会用到,到时回来查看比阅读文档方便。

Polygon操作经常用于机器人行业的感知系统中,特别是用于定义安全区域和障碍物边界框等任务。一些常见的应用包括:

  • 计算障碍物边界框与安全区域之间的重叠比例,以确定危险级别。
  • 验证障碍物是否进入自动驾驶车辆的危险区域。
  • 确定一些激光雷达点是否位于指定区域内。

应用实现

需求

  1. 生成随机多边形:创建两个随机多边形。
  2. 有效性检查和面积计算:验证多边形的有效性并计算它们的面积。
  3. 相交检测:确定两个多边形是否相交,并在相交时计算交叉多边形。
  4. 点包含检查:检查指定点是否位于交叉多边形内。

代码

#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 loop

namespace 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 one
    bg::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 invalid
    return 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 intersection
    if (checkPolygonIntersection(polygon_1, polygon_2))
    {
        // Print the intersection polygon points and area
        Polygon intersect_polygon = getOverlappingPolygon(polygon_1, polygon_2);
        printPolygon(intersect_polygon, "intersect");
        // Check if the origin point inside the polygon
        Point 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

网站公告

今日签到

点亮在社区的每一天
去签到