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 __
16 * / \ / \ / \ / \ / \ / \ / \
17 * / \ / \ / \ / \ / \ / \ / \
18 * . . . . . . . . . . . . . . . .
20 * _ L-4 ___ L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 ___ 3
21 * 1 1 1 1 W-2 W-2 W-2 W-2
22 * / \ / \ / \ / \ / \ / \ / \ /
23 * / \ / \ / \ / \ / \ / \ / \ /
24 * L-5 ___ L-4 ___ L-3 ___ L-2 ___ L-1 ___ 0 ___ 1 ___ 2 __
25 * 0 0 0 0 0 W-1 W-1 W-1
28 * 0 <= x < L x = distance along L = length
29 * 0 <= y < W y = distance across W = width
31 * Vertices are in reading order from diagram above ie x varies fastest.
33 * Where necessary, edges are counted anticlockwise from to-the-right:
42 * When we iterate over edges, we iterate first over vertices and then
43 * over edges 0 to 2, disregarding edges 3 to 5.
50 static double energy_function(const double vertices[N][3]) {
51 /* Energy has the following parts right now:
52 * - worst curvature radius
53 * - total angle subtended
68 * First flatten into plane _|_ PQ:
70 * R' = (R-P) x (Q-P)/|Q-P|
71 * S' = (S-P) x (Q-P)/|Q-P|
72 * Q' = (Q-P) x (Q-P)/|Q-P| = 0 = P'
84 * Now radius formula (wikipedia `Circle'), P1=R', P2=0, P3=S':
86 * |R'| * |S'| * | R' - S' |
87 * r = -------------------------
100 * gamma = cos -----------
107 * E = C sum gamma * l
108 * gamma gamma j in edges j j
112 static gsl_multimin_fminimizer *minimiser;
117 gsl_multimin_fminimizer_alloc(