I want to layout the graph of an RNA folding using BGL, it has a guaranteed plane structure and all edges should have the same length (there are two kinds of edges: the normal sequence, and bonds in red), like this:
rna secondary structure http://www.ncrna.org/frnadb/sec_structure/png/FR096703.png
namespace boost {
enum vertex_position_t { vertex_position };
BOOST_INSTALL_PROPERTY(vertex, position);
};
template<class PairIterator>
void layout(std::string seq, PairIterator begin, PairIterator end) {
using namespace boost; using namespace std;
// backbone edges + bonding edges
vector<pair<size_t,size_t>> edge_list(begin, end);
for(size_t i = 0 ; i < seq.size() - 1 ; i++)
edge_list.push_back(make_pair(i, i + 1));
typedef rectangle_topology<> topology;
typedef topology::point_type point;
boost::minstd_rand random;
topology space(random, -1000, -1000, 2000, 2000);
adjacency_list<vecS, vecS, undirectedS,
property<vertex_position_t, point>
> g(edge_list.begin(), edge_list.end(), seq.size());
random_graph_layout(g, get(vertex_position, g), space);
fruchterman_reingold_force_directed_layout(g, get(vertex_position, g), space,
cooling(linear_cooling<double>(100)));
// draw
}
However, this gives me a very random layout (for cooldown 100, 200, 400). Longer cooldowns just press the vertices into the corners (images show the complete layout). The edges seem to be consistently too long…

I’d like to specify a target length for the edges, and not have the simulation stop until it’s been reached within some margin.
My code is cobbled together from the boost samples, but I don’t need to stick to property maps etc, I just want a layout without having to resort to GraphViz.
It looks like the layout is starting to work in your righthand-most image, but that the space is too small for it to unfold into the right shape: maybe try using a more compact random layout to start with?
Or a stronger attractive force might help too. Note that according to the documentation the default attractive force function,
square_distance_attractive_forcedivides the attractive force by the edge descriptor — so smaller edge descriptors mean closer vertices.You can work out a “target-length” (sort of) for edges by considering that, for a well laid out planar graph, each vertex is only close to the vertices that it’s linked to by edges. This is pretty similar to the simple case where we have two vertices joined by a single edge (and if you had a regular grid of vertices, it wouldn’t be out by a factor of more than 4):
(vertex descriptor value, V)^2/distancefor all vertex pairs.distance^2/(edge descriptor value, E)for vertices linked by edges.These are in equilibrium when:
V2 / distance = distance2 / E
so:
distance = V(2/3) E(1/3)