2 * We try to find an optimal triangle grid
4 * Vertices in strip are numbered as follows:
6 * ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 ___ 3 ___ 4 __
8 * / \ / \ / \ / \ / \ / \ / \
9 * / \ / \ / \ / \ / \ / \ / \
10 * L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 ___ 3 ___ 4
11 * W-2 W-2 W-2 1 1 1 1 1
12 * \ / \ / \ / \ / \ / \ / \ /
13 * \ / \ / \ / \ / \ / \ / \ /
14 * ___ L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 ___ 3 __
17 * . . . . . . . . . . . . . . .
19 * L-4 ___ L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 ___ 3
20 * 1 1 1 1 W-2 W-2 W-2 W-2
21 * \ / \ / \ / \ / \ / \ / \ /
22 * \ / \ / \ / \ / \ / \ / \ /
23 * ___ L-4 ___ L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 __
27 * 0 <= x < L x = distance along L = length
28 * 0 <= y < W y = distance across W = width
30 * Vertices are in reading order from diagram above ie x varies fastest.
32 * W must be even. The actual location opposite (0,0) is (L-(W-1)/2,0),
33 * and likewise opposite (0,W-1) is ((W-1)/2,0).
35 * To label edges, we counte anticlockwise[*] from to-the-right:
44 * [*] That is, in the direction represented as anticlockwise for
45 * the vertices (0,*)..(4,*) in the diagram above; and of course
46 * that is clockwise for the vertices (L-5,*)..(L-1,*). The
47 * numbering has an actual discontinuity between (L-1,*) and (0,*).
49 * When we iterate over edges, we iterate first over vertices and then
50 * over edges 0 to 2, disregarding edges 3 to 5.
57 #define YMASK (~0u << LN2W)
58 #define XMASK (~YMASK)
60 /* Energy has the following parts right now:
63 * Edgewise expected vertex displacement
80 * Find R', the `expected' location of R, by
81 * reflecting S in M (the midpoint of QP).
87 * Giving energy contribution:
94 * By symmetry, this calculation gives the same answer
95 * with R and S exchanged. Looking at the projection in
102 * R' ,' d" = |SS'| = |RR'| = d
113 * We choose this value for l (rather than |RM|+|MS|, say, or |RM|)
114 * because we want this symmetry and because we're happy to punish
115 * bending more than uneveness in the metric.
117 * In practice to avoid division by zero we'll add epsilon to l and
118 * the huge energy ought then to be sufficient for the model to
119 * avoid being close to R=S.
122 static int edge_end2(int v1, int e) {
129 #define FOR_VERTEX(v) \
130 for ((v)=0; (v)<N; (v)++)
132 #define FOR_VPEDGE(v,e) \
133 for ((e)=0; (e)<6; (e)++)
135 #define EDGE_END2 edge_end2
137 #define FOR_VEDGE(v1,e,v2) \
139 if (((v2)= EDGE_END2((v1),(e))) >= 0) ; else
141 #define FOR_EDGE(v1,e,v2) \
143 FOR_VEDGE((v1),(e),(v2))
145 static double energy_function(const double vertices[N][3]) {
151 static gsl_multimin_fminimizer *minimiser;
156 gsl_multimin_fminimizer_alloc(