#include "minimise.h"
#include "mgraph.h"
-static void compute_vertex_areas(const Vertices vertices, double areas[N]);
+double vertex_areas[N], vertex_mean_edge_lengths[N], edge_lengths[N][V6];
+
static double best_energy= DBL_MAX;
static void addcost(double *energy, double tweight, double tcost, int pr);
/*---------- main energy computation and subroutines ----------*/
double compute_energy(const struct Vertices *vs) {
- double vertex_areas[N], energy;
+ double energy;
int printing;
- compute_vertex_areas(vs->a, vertex_areas);
+ compute_edge_lengths(vs->a);
+ compute_vertex_areas(vs->a);
energy= 0;
printing= printing_check(pr_cost);
if (printing) printf("cost > energy |");
COST(1e2, edgewise_vertex_displacement_cost(vs->a));
- COST(1e2, graph_layout_cost(vs->a,vertex_areas));
- COST(1e6, noncircular_rim_cost(vs->a));
+ COST(1e2, graph_layout_cost(vs->a));
+ COST(1e3, edge_length_variation_cost(vs->a));
+// COST(1e6, noncircular_rim_cost(vs->a));
if (printing) printf("| total %# e |", energy);
*energy += tenergy;
}
-static void compute_vertex_areas(const Vertices vertices, double areas[N]) {
+/*---------- Precomputations ----------*/
+
+void compute_edge_lengths(const Vertices vertices) {
+ int v1,e,v2;
+
+ FOR_EDGE(v1,e,v2)
+ edge_lengths[v1][e]= hypotD(vertices[v1],vertices[v2]);
+}
+
+void compute_vertex_areas(const Vertices vertices) {
int v0,v1,v2, e1,e2, k;
FOR_VERTEX(v0) {
- double total= 0.0;
+ double total= 0.0, edges_total=0;
int count= 0;
FOR_VEDGE(v0,e1,v1) {
v2= EDGE_END2(v0,e2);
if (v2<0) continue;
+ edges_total += edge_lengths[v0][e1];
+
double e1v[D3], e2v[D3], av[D3];
K {
e1v[k]= vertices[v1][k] - vertices[v0][k];
}
xprod(av, e1v, e2v);
total += magnD(av);
+
count++;
}
- areas[v0]= total / count;
+ vertex_areas[v0]= total / count;
+ vertex_mean_edge_lengths[v0]= edges_total / count;
}
}
return total_cost;
}
+/*---------- edge length variation ----------*/
+
+double edge_length_variation_cost(const Vertices vertices) {
+ double diff, cost= 0;
+ int v0, efwd,vfwd, eback;
+
+ FOR_EDGE(v0,efwd,vfwd) {
+ eback= edge_reverse(v0,efwd);
+ diff= edge_lengths[v0][efwd] - edge_lengths[v0][eback];
+ cost += diff*diff;
+ }
+ return cost;
+}
+
/*---------- noncircular rim cost ----------*/
double noncircular_rim_cost(const Vertices vertices) {