Search code examples
c++boostvertexboost-graph

BGL : get vertex descriptor with data


I want to get the vertex descriptor with the composant of the vertex, like this :

struct WayPoint{
std::pair<float, float> pos; // with this composant
};

the adjency list :

typedef boost::adjacency_list<  
    boost::listS,              
    boost::vecS,                
    boost::undirectedS,         
    WayPoint,                   
    WayPointConnection          
> WayPointGraph;
typedef WayPointGraph::vertex_descriptor WayPointID;
typedef WayPointGraph::edge_descriptor   WayPointConnectionID;

I built my graph and created all the vertices / edges .... the aim is to apply an astar on the graph.

void PathFinding::findMeAPath(std::pair<float, float>begin, std::pair<float, float>end)
{
    std::vector<WayPointID> p(boost::num_vertices(graphe)); 
    std::vector<float>      d(boost::num_vertices(graphe)); 
    WayPointID start = // I want to find the WayPointID with begin
    WayPointID goal = //same with end;
    shortest_path.clear();
    try {
        boost::astar_search
        (
        graphe, 
        start,  
        boost::astar_heuristic<WayPointGraph, float>(), 
        boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(astar_goal_visitor(goal)).weight_map(boost::get(&WayPointConnection::dist, graphe))
        );

    } catch(found_goal fg) { 

    for(WayPointID v = goal;; v = p[v]) {
        shortest_path.push_front(v);
        if(p[v] == v)
            break;
    }
    }
  }

Solution

  • You need to write a function to find a vertex given a position. The graph type that you have defined uses std::vector to store vertices, so the function will have to iterate through it and compare the queried position to each WayPoint. Something like this could do:

    std::pair<WayPointID, bool> find_vertex(const WayPoint& wp, const WayPointGraph& graph)
    {
      for (WayPointID id = 0; id < boost::num_vertices(graph); ++id)
      {
        if (equal(graph[id], wp))
          return std::make_pair(id, true);
      }
      return std::make_pair(0, false);
    }
    

    Note that the function returns a pair (Id + boolean flag) to indicate whether the search succeeded or not, so you would use it as follows:

    bool vertex_found;
    WayPointID start;
    std::tie (start, vertex_found) = find_vertex(begin, graphe);
    if (!vertex_found)
      // do something about it
    

    Also the function uses the following to compare positions:

    bool equal(const std::pair<float, float>& p1, const std::pair<float, float>& p2)
    {
      const float EPS = 1e-6;
      return (std::fabs(p1.first - p2.first) < EPS &&
              std::fabs(p1.second - p2.second) < EPS);
    }