c++ - 在 comparable_distance 中使用 boost 段失败,而 linestring 有效

标签 c++ boost boost-geometry

我正在尝试计算点和线段之间的距离。但是以下代码在运行时突然终止 (@comparable_distance)。

using namespace std;
namespace bg = boost::geometry;

class Vertex {
public:
    Vertex(int px, int py):x(px), y(py){}
    int x;
    int y;
};

BOOST_GEOMETRY_REGISTER_POINT_2D(Vertex, double, cs::cartesian, x, y)

typedef Vertex* vertref;

typedef bg::model::segment<vertref> segment_type;

std::vector<segment_type> segments;

int main()
{
    segment_type l(new Vertex(1,2), new Vertex(2,2));
    Vertex p(4,5);
    double comp_dist = 0;
    comp_dist = bg::comparable_distance(p, l);

    cout<<comp_dist<<endl;

    return 0;
}

如果我用线串替换 bg::model::segment;向它添加两点,它可以正常工作,如下所示......

using namespace std;
namespace bg = boost::geometry;

class Vertex {
public:
    Vertex(int px, int py):x(px), y(py){}
    int x;
    int y;
};

BOOST_GEOMETRY_REGISTER_POINT_2D(Vertex, double, cs::cartesian, x, y)

typedef Vertex* vertref;

typedef bg::model::linestring<vertref> segment_type;

std::vector<segment_type> segments;

int main()
{
    segment_type l;
    l.push_back(new Vertex(1,2));
    l.push_back(new Vertex(2,2));
    Vertex p(4,5);
    double comp_dist = 0;
    comp_dist = bg::comparable_distance(p, l);

    cout<<comp_dist<<endl;

    return 0;
}

知道我在使用段的第一个代码中做错了什么吗?

谢谢!

调用堆栈 ...

#0 0x40486f boost::geometry::traits::access<Vertex, 0u, void>::set(p=..., value=@0x63fde8: 1) (C:\Projects\test\main.cpp:17)
#1 0x403e14 boost::geometry::core_dispatch::access<boost::geometry::point_tag, Vertex, double, 0u, boost::integral_constant<bool, true> >::set(p=0x77b12580, value=@0x63fde8: 1) (C:/boost_1_68_0/boost/geometry/core/access.hpp:187)
#2 0x404182 boost::geometry::set<0u, Vertex*>(geometry=@0x63fe34: 0x77b12580, value=@0x63fde8: 1, dummy=0x0) (C:/boost_1_68_0/boost/geometry/core/access.hpp:321)
#3 0x40469a boost::geometry::detail::assign::assign_point_from_index<boost::geometry::model::segment<Vertex*>, Vertex*, 0u, 0u, 2u>::apply(geometry=..., point=@0x63fe34: 0x77b12580) (C:/boost_1_68_0/boost/geometry/algorithms/detail/assign_values.hpp:195)
#4 0x4045de boost::geometry::detail::assign_point_from_index<0u, Vertex*, boost::geometry::model::segment<Vertex*> >(geometry=..., point=@0x63fe34: 0x77b12580) (C:/boost_1_68_0/boost/geometry/algorithms/detail/assign_indexed_point.hpp:80)
#5 0x4049fc boost::geometry::dispatch::distance<Vertex, boost::geometry::model::segment<Vertex*>, boost::geometry::strategy::distance::projected_point<void, boost::geometry::strategy::distance::comparable::pythagoras<void> >, boost::geometry::point_tag, boost::geometry::segment_tag, boost::geometry::strategy_tag_distance_point_segment, false>::apply(point=..., segment=..., strategy=...) (C:/boost_1_68_0/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp:419)
#6 0x403f9b boost::geometry::resolve_strategy::comparable_distance::apply<Vertex, boost::geometry::model::segment<Vertex*> >(geometry1=..., geometry2=...) (C:/boost_1_68_0/boost/geometry/algorithms/detail/comparable_distance/interface.hpp:83)
#7 0x403f38 boost::geometry::resolve_variant::comparable_distance<Vertex, boost::geometry::model::segment<Vertex*> >::apply<boost::geometry::default_strategy>(geometry1=..., geometry2=..., strategy=...) (C:/boost_1_68_0/boost/geometry/algorithms/detail/comparable_distance/interface.hpp:106)
#8 0x403ff5 boost::geometry::comparable_distance<Vertex, boost::geometry::model::segment<Vertex*>, boost::geometry::default_strategy>(geometry1=..., geometry2=..., strategy=...) (C:/boost_1_68_0/boost/geometry/algorithms/detail/comparable_distance/interface.hpp:328)
#9 0x403fc9 boost::geometry::comparable_distance<Vertex, boost::geometry::model::segment<Vertex*> >(geometry1=..., geometry2=...) (C:/boost_1_68_0/boost/geometry/algorithms/detail/comparable_distance/interface.hpp:356)
#10 0x401518    main() (C:\Projects\test\main.cpp:30)

最佳答案

Segment Concept model::segment 建模, 它采用一个模板参数来模拟 Point .

现在你使用了:

typedef Vertex *vertref;

typedef bg::model::segment<vertref> segment_type;

请注意 vertref 实际上模拟点概念。因此,相比之下,请考虑:

Live On Coliru

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

struct Vertex {
    double x;
    double y;
};

BOOST_GEOMETRY_REGISTER_POINT_2D(Vertex, double, bg::cs::cartesian, x, y)

typedef bg::model::segment<Vertex> segment_type;

int main() {
    segment_type l({1, 2}, {2, 2});
    Vertex p {4, 5};

    auto comp_dist = bg::comparable_distance(p, l);

    std::cout << comp_dist << "\n";
}

打印:

13

确实13是实际距离的平方:enter image description here

奖金

作为对评论的回应,是的,甚至还有一个开箱即用的模型用于引用点(来自其他几何图形)的线段。下面是如何使用 referring_segment<> :

Live On Coliru

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

struct Vertex {
    double x;
    double y;
};

BOOST_GEOMETRY_REGISTER_POINT_2D(Vertex, double, bg::cs::cartesian, x, y)

typedef bg::model::referring_segment<Vertex> segment_type;

int main() {
    Vertex A{1,2},
           B{2,2};
    segment_type l(A, B);
    Vertex p {4, 5};

    std::cout << bg::distance(p, l) << "\n";

    bg::multiply_value(A, -1);
    bg::multiply_value(B, -1);
    std::cout << bg::distance(p, l) << "\n";
}

打印突变前后的距离:

3.60555
8.60233

这再次符合您期望看到的内容:enter image description here

注意事项:

  1. 使用new在 C++ 中几乎总是一个错误。这个错误最常由来自垃圾收集语言(如 Java 或 C#)的初学者犯(Why should C++ programmers minimize use of 'new'?)
  2. 类型不一致(成员 xyint )

关于c++ - 在 comparable_distance 中使用 boost 段失败,而 linestring 有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53014763/

相关文章:

c++ - 使用boost库查找交点

c++ - Boost 图形库在应用 dijkstra 算法时导致错误

c++ - 比较字 rune 字与 C++ 中的 Std::String

c++ - 如果没有一堆 if/else 语句,你将如何做到这一点?

android - JNI 函数中的两个整数求和返回错误值

c++ - boost::process 如何知道进程何时退出 "gracefully or not"?

c++ - 如何返回由 boost::varaint 返回类型中包含的类型的子集构成的 boost::variant

c++ - 可以从并行线程完成对 boost 的 rtree 的查询吗?

c++ - 如何使用 Boost::Geometry 解析 wkt Geometrycollection?

c++ - __typeof 和 typeof 有什么区别吗?