提升内点的几何多边形距离
boost geometry polygon distance for inside point
我正在使用 boost::geometry
来处理一些几何任务。我有两个要求需要满足:
- 处理点 -> 多边形交点(在内部或外部)。这对
boost::geometry::within
非常有用,所以很好
- 获取任意点到多边形最近边的距离。虽然
boost::geometry::distance
可以正确处理多边形之外的点,但它似乎认为多边形是实体的。所以多边形内的每个点显然与多边形的距离为 0。
我尝试用 inner/outer 东西进行试验,想知道是否有可能获得多边形内外点的距离。
我决定使用以下方法,到目前为止似乎提供了正确的结果:
const TPolygonPoint pt{ x, y };
auto distance = std::numeric_limits<float>::max();
if(boost::geometry::within(pt, mPolygon)) {
boost::geometry::for_each_segment(mPolygon, [&distance, &pt](const auto& segment) {
distance = std::min<float>(distance, boost::geometry::distance(segment, pt));
});
} else {
distance = boost::geometry::distance(pt, mPolygon);
}
return distance;
如果有人知道更快或更好的方法,请发表评论:)
如果点在多边形内部,您可以使用 comparable_distance
而不是 distance
算法来加快代码速度。您不需要计算每个分段点对的确切距离。使用 comparable_distance
找到距离给定点最近的多边形线段,然后使用 distance
算法计算实际距离。
auto distance = std::numeric_limits<float>::max();
if(boost::geometry::within(pt, mPolygon))
{
Segment nearestSegment;
boost::geometry::for_each_segment(mPolygon,
[&distance, &pt, &nearestSegment](const auto& segment)
{
double cmpDst = boost::geometry::comparable_distance(segment,pt);
if (cmpDst < distance)
{
distance = cmpDst;
nearestSegment = segment; // UPDATE NEAREST SEGMENT
}
});
// CALCULATE EXACT DST
distance = boost::geometry::distance(nearestSegment,pt);
} else {
distance = boost::geometry::distance(pt, mPolygon);
}
为了获得最佳性能,您应该使用带有 boost::geometry::index 的 RTree。创建 RTree 是有成本的,但是计算一个点到任何(多)多边形环的距离会快得多。示例代码:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <vector>
int main()
{
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::polygon<point> polygon;
point p{ 0, 0 };
// create some polygon and fill it with data
polygon poly;
double a = 0;
double as = bg::math::two_pi<double>() / 100;
for (int i = 0; i < 100; ++i, a += as)
{
double c = cos(a);
double s = sin(a);
poly.outer().push_back(point{10 * c, 10 * s});
poly.inners().resize(1);
poly.inners()[0].push_back(point{5 * c, 5 * s});
}
// make sure it is valid
bg::correct(poly);
// create rtree containing objects of type bg::model::pointing_segment
typedef bg::segment_iterator<polygon const> segment_iterator;
typedef std::iterator_traits<segment_iterator>::value_type segment_type;
bgi::rtree<segment_type, bgi::rstar<4> > rtree(bg::segments_begin(poly),
bg::segments_end(poly));
// get 1 nearest segment
std::vector<segment_type> result;
rtree.query(bgi::nearest(p, 1), std::back_inserter(result));
BOOST_ASSERT(!result.empty());
std::cout << bg::wkt(result[0]) << ", " << bg::distance(p, result[0]) << std::endl;
return 0;
}
你可以直接使用boost::geometry::distance,如果你添加一个内边界到与外边界重合的多边形[Polygon Concept]。
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main() {
typedef bg::model::point<int, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t;
polygon_t poly1;
bg::append (poly1.outer(), point_t (1, -1));
bg::append (poly1.outer(), point_t (1, 1));
bg::append (poly1.outer(), point_t (-1, 1));
bg::append (poly1.outer(), point_t (-1, -1));
bg::append (poly1.outer(), point_t (1, -1));
poly1.inners().resize (1);
bg::append (poly1.inners()[0], point_t (1, -1));
bg::append (poly1.inners()[0], point_t (1, 1));
bg::append (poly1.inners()[0], point_t (-1, 1));
bg::append (poly1.inners()[0], point_t (-1, -1));
bg::append (poly1.inners()[0], point_t (1, -1));
point_t myPoint (0, 0);
std::cout << "Minimal distance: " << bg::distance (poly1, myPoint) << std::endl;
std::cout << "Is within: " << bg::within (myPoint, poly1) << std::endl;
return 0;
}
-> 将 return:
Minimal distance: 1
Is within: 0
但是,如果您这样做,严格位于多边形内部的点将被认为位于 'outside' 多边形 boost::geometry::within 处。如果您想要这两种功能,您可以维护两个单独的多边形 - 一个有内部边界,一个没有。
我正在使用 boost::geometry
来处理一些几何任务。我有两个要求需要满足:
- 处理点 -> 多边形交点(在内部或外部)。这对
boost::geometry::within
非常有用,所以很好 - 获取任意点到多边形最近边的距离。虽然
boost::geometry::distance
可以正确处理多边形之外的点,但它似乎认为多边形是实体的。所以多边形内的每个点显然与多边形的距离为 0。
我尝试用 inner/outer 东西进行试验,想知道是否有可能获得多边形内外点的距离。
我决定使用以下方法,到目前为止似乎提供了正确的结果:
const TPolygonPoint pt{ x, y };
auto distance = std::numeric_limits<float>::max();
if(boost::geometry::within(pt, mPolygon)) {
boost::geometry::for_each_segment(mPolygon, [&distance, &pt](const auto& segment) {
distance = std::min<float>(distance, boost::geometry::distance(segment, pt));
});
} else {
distance = boost::geometry::distance(pt, mPolygon);
}
return distance;
如果有人知道更快或更好的方法,请发表评论:)
如果点在多边形内部,您可以使用 comparable_distance
而不是 distance
算法来加快代码速度。您不需要计算每个分段点对的确切距离。使用 comparable_distance
找到距离给定点最近的多边形线段,然后使用 distance
算法计算实际距离。
auto distance = std::numeric_limits<float>::max();
if(boost::geometry::within(pt, mPolygon))
{
Segment nearestSegment;
boost::geometry::for_each_segment(mPolygon,
[&distance, &pt, &nearestSegment](const auto& segment)
{
double cmpDst = boost::geometry::comparable_distance(segment,pt);
if (cmpDst < distance)
{
distance = cmpDst;
nearestSegment = segment; // UPDATE NEAREST SEGMENT
}
});
// CALCULATE EXACT DST
distance = boost::geometry::distance(nearestSegment,pt);
} else {
distance = boost::geometry::distance(pt, mPolygon);
}
为了获得最佳性能,您应该使用带有 boost::geometry::index 的 RTree。创建 RTree 是有成本的,但是计算一个点到任何(多)多边形环的距离会快得多。示例代码:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <vector>
int main()
{
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::polygon<point> polygon;
point p{ 0, 0 };
// create some polygon and fill it with data
polygon poly;
double a = 0;
double as = bg::math::two_pi<double>() / 100;
for (int i = 0; i < 100; ++i, a += as)
{
double c = cos(a);
double s = sin(a);
poly.outer().push_back(point{10 * c, 10 * s});
poly.inners().resize(1);
poly.inners()[0].push_back(point{5 * c, 5 * s});
}
// make sure it is valid
bg::correct(poly);
// create rtree containing objects of type bg::model::pointing_segment
typedef bg::segment_iterator<polygon const> segment_iterator;
typedef std::iterator_traits<segment_iterator>::value_type segment_type;
bgi::rtree<segment_type, bgi::rstar<4> > rtree(bg::segments_begin(poly),
bg::segments_end(poly));
// get 1 nearest segment
std::vector<segment_type> result;
rtree.query(bgi::nearest(p, 1), std::back_inserter(result));
BOOST_ASSERT(!result.empty());
std::cout << bg::wkt(result[0]) << ", " << bg::distance(p, result[0]) << std::endl;
return 0;
}
你可以直接使用boost::geometry::distance,如果你添加一个内边界到与外边界重合的多边形[Polygon Concept]。
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main() {
typedef bg::model::point<int, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t;
polygon_t poly1;
bg::append (poly1.outer(), point_t (1, -1));
bg::append (poly1.outer(), point_t (1, 1));
bg::append (poly1.outer(), point_t (-1, 1));
bg::append (poly1.outer(), point_t (-1, -1));
bg::append (poly1.outer(), point_t (1, -1));
poly1.inners().resize (1);
bg::append (poly1.inners()[0], point_t (1, -1));
bg::append (poly1.inners()[0], point_t (1, 1));
bg::append (poly1.inners()[0], point_t (-1, 1));
bg::append (poly1.inners()[0], point_t (-1, -1));
bg::append (poly1.inners()[0], point_t (1, -1));
point_t myPoint (0, 0);
std::cout << "Minimal distance: " << bg::distance (poly1, myPoint) << std::endl;
std::cout << "Is within: " << bg::within (myPoint, poly1) << std::endl;
return 0;
}
-> 将 return:
Minimal distance: 1
Is within: 0
但是,如果您这样做,严格位于多边形内部的点将被认为位于 'outside' 多边形 boost::geometry::within 处。如果您想要这两种功能,您可以维护两个单独的多边形 - 一个有内部边界,一个没有。