X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=bgl.cpp;h=28c6ee6fe45816724bf5148d931f40ea3a40ef70;hb=d9aa142b98fffa94e33f47056090d42f8d6afae3;hp=e75918a9d6d8b5799e51caedb2ae39072728b7db;hpb=456ce271eea85ff5acfe6a4416fa6c085d998c64;p=moebius2.git diff --git a/bgl.cpp b/bgl.cpp index e75918a..28c6ee6 100644 --- a/bgl.cpp +++ b/bgl.cpp @@ -22,10 +22,11 @@ extern "C" { } /* - * edge descriptor f = 00 | e | y | x - * 3 YBITS XBITS + * edge descriptor f = 0000 | e | y | x + * 3 YBITS XBITS * - * e is 0..5. The edge is edge e out of vertex (x,y). + * e is 0..6. The edge is edge e out of vertex (x,y), or if + * e==6 it's the `at end' value for the out edge iterator. * * BGL expects an undirected graph's edges to have two descriptors * each, one in each direction (otherwise e would be just 0..2). @@ -44,28 +45,36 @@ extern "C" { */ #define VMASK (YMASK|XMASK) -#define ESHIFT (YBITS|XBITS) +#define ESHIFT (YBITS+XBITS) class Graph { }; // this is a dummy as our graph has no actual representation using namespace boost; /* - * We use the following alternative numbering for iterating over edges: + * We iterate over edges in the following order: * - * ix: \0 /1 - * \ / - * ___ 0 __ - * 2 1 3 - * / \ - * 4/ 5\ + * \#0 /1# + * \ / + * ___ 0 __ + * #2 1 #3 + * / \ + * #4/ #5\ and finally #6 is V6 * * - * This numbering permits the order-4 nodes at the strip's edge - * to have a contiguous edge iterator values 2..5 or 0..3. + * This ordering permits the order-4 nodes at the strip's edge + * to have a contiguous edge iterator values. The iterator + * starts at #0 which is edge 2 (see mgraph.h), or #2 (edge 3). */ -static const int oee_edgemap[V6]= - { 2< { - int v, ix, f; - - void setf() { f= v | oee_edgemap[ix]; } + int f; public: - void increment() { ix++; setf(); } - bool equal(OutEdgeIterator const& other) const { return ix == other.ix; } + void increment() { + //printf("incrementing f=%03x..",f); + f += oei_edge_delta[f>>ESHIFT]; + //printf("%03x\n",f); + } + bool equal(OutEdgeIterator const& other) const { return f == other.f; } int const& dereference() const { return f; } OutEdgeIterator() { } - OutEdgeIterator(int _v, int _ix) : v(_v), ix(_ix) { setf(); } + OutEdgeIterator(int _f) : f(_f) { } + OutEdgeIterator(int v, int e) : f(e< VertexIterator; @@ -122,14 +137,18 @@ namespace boost { // Concept IncidenceGraph: inline int source(int f, const Graph&) { return f&VMASK; } - inline int target(int f, const Graph&) { return EDGE_END2(f&VMASK, f>>ESHIFT); } + inline int target(int f, const Graph&) { + int v2= EDGE_END2(f&VMASK, f>>ESHIFT); + //printf("traversed %03x..%02x\n",f,v2); + return v2; + } inline std::pair out_edges(int v, const Graph&) { return std::make_pair(OutEdgeIterator(v, OutEdgeIterator::voe_min(v)), OutEdgeIterator(v, OutEdgeIterator::voe_max(v))); } inline unsigned out_degree(int v, const Graph&) { - return OutEdgeIterator::voe_max(v) - OutEdgeIterator::voe_min(v); + return OutEdgeIterator::voe_degree(v); } // Concept VertexListGraph: @@ -182,11 +201,19 @@ double graph_layout_cost(const Vertices v, const double vertex_areas[N]) { double a1= vertex_areas[v1]; single_source_shortest_paths(v1, edge_weights, vertex_distances); FOR_VERTEX(v2) { + if (v1 == v2) continue; double a2= vertex_areas[v2]; double d2= hypotD2plus(v[v1],v[v2], d2_epsilon); - double sd= vertex_distances[v2] / d2; - double sd2= sd*sd; - total_cost += a1*a2 * (sd2 - 1) / (d2*d2); + double s= vertex_distances[v2]; + double s2= s*s + d2_epsilon; + double sd2= s2 / d2; + double cost_contrib= a1*a2 * (sd2 - 1) / (d2*d2); + if (cost_contrib < -1e-4) { + printf("layout %03x..%03x (a=%g,%g) s=%g s2=%g d2=%g sd2=%g" + " cost+=%g\n", v1,v2, a1,a2, s,s2,d2,sd2, cost_contrib); + abort(); + } + total_cost += cost_contrib; } } return total_cost;