Update.
[universe.git] / mash.cc
1
2 #include <iostream>
3 #include <fstream>
4 #include <cmath>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <string.h>
10
11 using namespace std;
12
13 #include "misc.h"
14 #include "universe.h"
15
16 int main(int argc, char **argv) {
17   int nb_heur = 50;
18   int w = 1000, h = 1000;
19   Universe universe(nb_heur + 1, w, h);
20
21   {
22     int nb = 100;
23     scalar_t xs[nb], ys[nb];
24     for(int k = 0; k < nb; k++) {
25       scalar_t alpha, radius;
26       if(k < nb/2) {
27         alpha = - (M_PI / scalar_t(nb/2)) * k;
28         radius = 400;
29       } else {
30         alpha = - (M_PI / scalar_t(nb/2)) * (nb - k - 1);
31         radius = 350;
32       }
33       xs[k] = scalar_t(w)/2 + radius * cos(-alpha);
34       ys[k] = scalar_t(h)/2 + radius * sin(-alpha);
35     }
36     Polygon *p;
37     p = new Polygon(1.0, 0.0, 0.0, 0.0, xs, ys, nb);
38     p->set_position(scalar_t(w/2), scalar_t(h) * 0.75, 0);
39     p->set_speed(0, 0, 0);
40     universe.initialize(p);
41     universe.add_polygon(p);
42   }
43
44   Polygon *blocks[nb_heur];
45
46   for(int i = 0; i < nb_heur; i++) {
47
48     int nb_max_edges = 10;
49     int xt[nb_max_edges * nb_max_edges], yt[nb_max_edges * nb_max_edges];
50     int used[nb_max_edges * nb_max_edges];
51     int fail, x, y, n;
52     do {
53       fail = 0;
54       for(int k = 0; k < nb_max_edges * nb_max_edges; k++) {
55         used[k] = 0;
56       }
57       x = 0; y = 0; n = 0;
58       while(!used[x + nb_max_edges * y]) {
59         used[x + nb_max_edges * y] = 1;
60         xt[n] = x; yt[n] = y;
61         n++;
62         switch(int(drand48() * 4)) {
63         case 0: x++; break;
64         case 1: x--; break;
65         case 2: y++; break;
66         case 3: y--; break;
67         default: abort();
68         }
69         if(x < 0) x = 0;
70         else if(x >= nb_max_edges) x = nb_max_edges-1;
71         if(y < 0) y = 0;
72         else if(y >= nb_max_edges) y = nb_max_edges-1;
73       }
74       fail = (n < 10) || (x != 0) || (y != 0);
75     } while(fail);
76
77     scalar_t xs[nb_max_edges], ys[nb_max_edges];
78     int nb_edges = 0;
79     for(int l = 0; l < n; l++) {
80       int pl = (l + n - 1)%n, nl = (l + 1)%n;
81       if(xt[nl] - xt[l] != xt[l] - xt[pl] || yt[nl] - yt[l] != yt[l] - yt[pl]) {
82         xs[nb_edges] = scalar_t(xt[l]) * 25;
83         ys[nb_edges] = scalar_t(yt[l]) * 25;
84         nb_edges++;
85       }
86     }
87
88     cout << "n = " << n << " nb_edges = " << nb_edges << endl;
89
90     scalar_t red, green, blue;
91     do {
92       red = scalar_t(16 * int(drand48() * 16))/255.0;
93       green = scalar_t(16 * int(drand48() * 16))/255.0;
94       blue = scalar_t(16 * int(drand48() * 16))/255.0;
95     } while((red > 0.1 && green > 0.1 && blue > 0.1) ||
96             (red < 0.9 && green < 0.9 && blue < 0.9));
97     blocks[i] = new Polygon(1.0, red, green, blue, xs, ys, nb_edges);
98     do {
99       blocks[i]->set_position(drand48() * w * 0.9 + w * 0.05, drand48() * 3 * h / 4 + h/8, M_PI * drand48());
100       blocks[i]->set_speed(0, 0, 0);
101       // universe.initialize(blocks[i]);
102       for(int j = 0; j < i + 1; j++) {
103         universe.initialize(blocks[j]);
104       }
105     } while(universe.collide(blocks[i]));
106     universe.add_polygon(blocks[i]);
107     cout << "added " << i+1 << " blocks." << endl;
108   }
109
110   scalar_t dt = 0.1;
111
112   for(int n = 0; n < 100000; n++) {
113     for(int i = 0; i < nb_heur; i++) {
114       blocks[i]->apply_force(dt, blocks[i]->_center_x, blocks[i]->_center_y, 0, 0.25);
115     }
116     universe.update(dt);
117     if(n%1000 == 0) {
118       char buffer[1024];
119       sprintf(buffer, "/tmp/mash_%06d.fig", n);
120       XFigTracer tracer(buffer);
121       universe.print_xfig(&tracer);
122       cout << "Wrote " << buffer << endl;
123     }
124   }
125
126   XFigTracer tracer("/tmp/mash.fig");
127   universe.print_xfig(&tracer);
128
129   exit(0);
130 }