用成对的向量增加几何面积?

boost geometry area with a vector of pairs?

有什么方法可以让 boost::geometry::area 使用成对的向量吗?它在这里 https://www.boost.org/doc/libs/1_75_0/libs/geometry/doc/html/geometry/reference/algorithms/area/area_1.html 说它应该与 MultiPoint 一起工作。所以我调用了 BOOST_GEOMETRY_REGISTER_MULTI_POINT - 它适用于 convex_hull,但它不适用于 area。或者我必须创建一个多边形并将点附加到它,如下所示: https://www.boost.org/doc/libs/1_75_0/libs/geometry/doc/html/geometry/reference/models/model_polygon.html

这是我的代码:

#include <iostream>
#include <cstdlib>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/multi/geometries/register/multi_point.hpp>

BOOST_GEOMETRY_REGISTER_POINT_2D(decltype(std::pair<double, double>{}), double, cs::cartesian, first, second)
BOOST_GEOMETRY_REGISTER_MULTI_POINT(decltype(std::vector<std::pair<double, double>>{}))

using MultiPoint = std::vector<std::pair<double, double>>;
MultiPoint getHull(const MultiPoint& points)
{
  MultiPoint hull{};
  boost::geometry::convex_hull(points, hull);
  return hull; // This returns a vector of pairs of points respresenting a hull
}
double getHullArea(const MultiPoint& points)
{
  return boost::geometry::area(points); // This always return 0
}

int main()
{
    // Unit square
    auto points = MultiPoint{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0,0}};
    auto hull = getHull(points); // This works as expected
    auto area = getHullArea(hull); // This always return 0
}

是的,它支持多点。你会得到记录的 behaviour:

所以,你得到的面积是 0,就像你应该期待的那样。

很明显你想适应一个区域几何体。假设您的配对是 Points that form a Ring.

using Point = std::pair<double, double>;
using Ring  = std::vector<Point>;

BOOST_GEOMETRY_REGISTER_POINT_2D(Point, double, cs::cartesian, first, second)
BOOST_GEOMETRY_REGISTER_RING(Ring)

现在它如您所料的那样工作了:

Live On Coliru

#include <iostream>
#include <cstdlib>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>
namespace bg = boost::geometry;

using Point = std::pair<double, double>;
using Ring  = std::vector<Point>;

BOOST_GEOMETRY_REGISTER_POINT_2D(Point, double, cs::cartesian, first, second)
BOOST_GEOMETRY_REGISTER_RING(Ring)

Ring getHull(const Ring& points) {
    Ring hull;
    bg::convex_hull(points, hull);
    return hull;
}

double getArea(const Ring& points) {
    return bg::area(points);
}

int main() {
    for (Ring points : {
             Ring{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}},
             Ring{{0, 0}, {0, 2}, {3, 2}, {3, 1}, {1, 1}, {1, 0}, {0, 0}},
         })
    {
        std::cout << "-----\nInput:\t" << bg::wkt(points) << "\n";
        if (std::string reason; !bg::is_valid(points)) {
            std::cout << "Input:\t" << reason << "\n";
            bg::correct(points);
            std::cout << bg::wkt(points) << "\n";
        }

        std::cout << "Hull:\t"      << bg::wkt(getHull(points)) << "\n";
        std::cout << "Area:\t"      << getArea(points)          << "\n";
        std::cout << "Hull Area:\t" << getArea(getHull(points)) << "\n";
    }
}

版画

-----
Input:  POLYGON((0 0,0 1,1 1,1 0,0 0))
Hull:   POLYGON((0 0,0 1,1 1,1 0,0 0))
Area:   1
Hull Area:      1
-----
Input:  POLYGON((0 0,0 2,3 2,3 1,1 1,1 0,0 0))
Hull:   POLYGON((0 0,0 2,3 2,3 1,1 0,0 0))
Area:   4
Hull Area:      5

如您所见,我添加了一个更有趣的示例: