查找所有线段=距图形中某点的某一距离内的边,如何将增强图与增强几何相结合?

时间:2013-08-19 16:28:07

标签: c++ geometry boost-graph boost-geometry

我在游戏设置中有一组用户路径(2 dim),它们被建模为一组线(弧)和航点=顶点。整个路径集可以看作是一个图形,其中边是具有长度,概率等附加属性的线段。

现在我必须确定一组(直线)线段=距离用户当前位置一定距离内的边缘,以便找到用户在图表中的位置。

如何在不重新发明轮子的情况下尽可能简单地实现这一点?如何有效地实施搜索?

我想过使用boost-graph来处理图形并将其与boost-geometry结合起来。 例如。请参阅在boost-graph中使用捆绑属性的TrajGraph:

struct Tvertex
{
    float x, y; //vertex=waypoint position
};

struct Tarc_segment
{
    float len, curvature, prob; //line segment=edge properties
};

typedef adjacency_list<vecS, vecS, directedS, Tvertex, Tarc_segment> TrajGraph;

现在,为了将线段存储为边缘属性,可以添加boost几何体的model :: linestring,并使用boost-geometry的最近邻居查询来查找线段。但afaik boost-geometry不允许像boost-graph那样将属性附加到线串。那么如何从线串获得边缘?

一个简单的蛮力解决方案可能是遍历图表的整个边缘列表并计算到每个线段的距离。有关如何计算直线段的距离,请参阅herehere

2 个答案:

答案 0 :(得分:2)

当然可以在Boost.Geometry中将属性附加到线串,实际上Boost.Geometry就是为了做这些事情。您可以从boost :: geometry :: model :: linestring派生,或者实现任何其他基于范围的结构(例如std :: vector)并将其注册为线串。请参阅c03示例。

对于与Boost.Graph的关系,请参阅Boost.Geometry中的一个示例:07_a07_b,其中完成了类似的操作。在那里做的是将Boost.Geometry线串存储到Boost.Graph边缘(带有属性)以及其他属性,这是另一种方法。

答案 1 :(得分:1)

对于线条,我会使用Hesse Normal Form为每个线段计算距离并选择或丢弃该线条。

Hesse Normal Form

/// Hesse Normal Form
/// \NOTE: Since negative distances from the origin are accepted, it is almost
///        a Hesse Normal Form, only)
template<class ScalarType>
class HesseNormalForm2D
{
    public:
    typedef ScalarType Scalar;
    typedef Normal2D<Scalar> Normal;
    typedef Vector2D<Scalar> Vector;
    typedef Point2D<Scalar> Point;
    typedef Line2D<Scalar> Line;

    public:
    /// An invalid line initialized with NaN.
    static HesseNormalForm2D nan() { return HesseNormalForm2D(Normal::nan(), Scalar::nan()); }

    /// An undefined line.
    HesseNormalForm2D() {}

    /// A line defined by a normal and a distance form the origin.
    explicit HesseNormalForm2D(const Normal& n, const Scalar& d)
    :   m_n(n), m_d(d)
    {}

    /// The Hesse Normal Form of a line.
    /// ATTENTION The scalar value d of the line may be negative.
    explicit HesseNormalForm2D(const Point& p, const Vector& v) {
        m_n = -orthonormal(v);
        m_d = scalar_product(m_n, Vector(p));
    }

    /// The Hesse Normal Form of a line.
    /// ATTENTION The scalar value d of the line may be negative.
    explicit HesseNormalForm2D(const Point& p0, const Point& p1) {
        m_n = -orthonormal(p1 - p0);
        m_d = scalar_product(m_n, Vector(p0));
    }

    /// The Hesse Normal Form of a line.
    /// ATTENTION The scalar value d of the line may be negative.
    explicit HesseNormalForm2D(const Line&);

    /// The normal.
    const Normal& n() const { return m_n; }
    /// The normal.
    Normal& n() { return m_n; }
    /// The distance from the origin.
    const Scalar& d() const { return m_d; }
    /// The distance from the origin.
    Scalar& d() { return m_d; }

    /// The distance of a point to the line.
    /// \NOTE The point x on the line L with the smallest distance to p is:
    ///       x = p - L(p) * L.n()
    Scalar operator () (const Point& p) const {
        return scalar_product(Vector(p), n()) - d();
    }

    private:
    Normal m_n;
    Scalar m_d;
};

为了概括它,考虑到你需要的不同属性(Line,Arc,......),你会有一个不同的类。