999c753f1794d551d1db27a04f1f68f0c2db7167
[universe.git] / generate.cc
1
2 ////////////////////////////////////////////////////////////////////
3 // START_IP_HEADER                                                //
4 //                                                                //
5 // Written by Francois Fleuret                                    //
6 // Contact <francois.fleuret@idiap.ch> for comments & bug reports //
7 //                                                                //
8 // END_IP_HEADER                                                  //
9 ////////////////////////////////////////////////////////////////////
10
11 // for i in {0..49}; do u=$(printf %03d $i); mkdir $u && mv dyn_${u}* ${u}; done
12
13 #include <iostream>
14 #include <fstream>
15 #include <cmath>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <sys/stat.h>
22
23 using namespace std;
24
25 #include "misc.h"
26 #include "task.h"
27 #include "simple_window.h"
28 #include "universe.h"
29 #include "plotter.h"
30 #include "retina.h"
31 #include "manipulator.h"
32 #include "intelligence.h"
33 #include "canvas_cairo.h"
34
35 void generate_png(Universe *universe, scalar_t scale, FILE *file) {
36   CanvasCairo canvas(scale, universe->width(), universe->height());
37   canvas.set_line_width(1.0 / scale);
38   universe->draw(&canvas);
39   canvas.write_png(file);
40 }
41
42 int main(int argc, char **argv) {
43   const scalar_t world_width = 400;
44   const scalar_t world_height = 400;
45   const scalar_t grab_start_x = world_width * 0.5;
46   const scalar_t grab_start_y = world_height * 0.75;
47   const int nb_blocks = 1;
48   const scalar_t block_size = 80;
49
50   const scalar_t dt = 0.1;
51   const int nb_steps = 5;
52   const int nb_iterations_per_steps = 20;
53
54   Universe *universe;
55   Polygon *grabbed_polygon;
56
57   if(argc < 2 || argc > 3) {
58     cerr << argv[0] << " <nb pairs to generate> [<dir> [<seed>]]" << endl;
59     exit(1);
60   }
61
62   int nb_pairs = atoi(argv[1]);
63
64   char dir[1024] = "/tmp/";
65
66   if(argc > 2) {
67     strncpy(dir, argv[2], sizeof(dir) / sizeof(char) - 1);
68   }
69
70   if(argc > 3) {
71     srand48(atoi(argv[1]));
72   }
73
74   universe = new Universe(10, world_width, world_height);
75
76   for(int n = 0; n < nb_pairs; n++) {
77     if(n%1000 == 0) { cout << "Example #" << n+1 << endl; }
78
79     do {
80       universe->clear();
81
82       const int nb_attempts_max = 100;
83       int nb_attempts = 0;
84
85       for(int u = 0; u < nb_blocks; u++) {
86         Polygon *pol = 0;
87
88         nb_attempts = 0;
89
90         do {
91           scalar_t x[] = {
92             - block_size * 0.4,
93             + block_size * 0.4,
94             + block_size * 0.4,
95             - block_size * 0.4,
96           };
97
98           scalar_t y[] = {
99             - block_size * 0.6,
100             - block_size * 0.6,
101             + block_size * 0.6,
102             + block_size * 0.6,
103           };
104
105           scalar_t delta = block_size / sqrt(2.0);
106           scalar_t object_center_x = delta + (world_width - 2 * delta) * drand48();
107           scalar_t object_center_y = delta + (world_height - 2 * delta) * drand48();
108           scalar_t red, green, blue;
109           red = 1.00;
110           green = red;
111           blue = red;
112           delete pol;
113           pol = new Polygon(0.5,
114                             red, green, blue,
115                             x, y, sizeof(x)/sizeof(scalar_t));
116           pol->set_position(object_center_x, object_center_y, M_PI * 2 * drand48());
117           pol->set_speed(0, 0, 0);
118           universe->initialize_polygon(pol);
119           nb_attempts++;
120         } while(nb_attempts < nb_attempts_max && universe->collide(pol));
121
122         if(nb_attempts == nb_attempts_max) {
123           delete pol;
124           u = 0;
125           universe->clear();
126           nb_attempts = 0;
127         } else {
128           universe->add_polygon(pol);
129         }
130       }
131
132       grabbed_polygon = universe->pick_polygon(grab_start_x, grab_start_y);
133     } while(!grabbed_polygon);
134
135     const scalar_t scaling = 0.16;
136
137     CanvasCairo grab_trace(scaling, world_width, world_height);
138
139     {
140       char buffer[1024];
141       sprintf(buffer, "%s/%03d/", dir, n/1000);
142       mkdir(buffer, 0777);
143     }
144
145     scalar_t grab_relative_x = grabbed_polygon->relative_x(grab_start_x, grab_start_y);
146     scalar_t grab_relative_y = grabbed_polygon->relative_y(grab_start_x, grab_start_y);
147
148     {
149       int n = 36;
150       scalar_t xp[n], yp[n];
151       for(int k = 0; k < n; k++) {
152         scalar_t radius = 1/scaling;
153         scalar_t alpha = 2 * M_PI * scalar_t(k) / scalar_t(n);
154         xp[k] = grab_start_x + radius * cos(alpha);
155         yp[k] = grab_start_y + radius * sin(alpha);
156       }
157       grab_trace.set_drawing_color(0.0, 0.0, 0.0);
158       grab_trace.set_line_width(2.0);
159       grab_trace.draw_polygon(1, n, xp, yp);
160     }
161
162     for(int s = 0; s < nb_steps; s++) {
163       {
164         char buffer[1024];
165         sprintf(buffer, "%s/%03d/dyn_%06d_world_%03d.png", dir, n/1000, n, s);
166         FILE *file = fopen(buffer, "w");
167         generate_png(universe, scaling, file);
168         fclose(file);
169       }
170
171       for(int i = 0; i < nb_iterations_per_steps; i++) {
172         scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y);
173         scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y);
174         grabbed_polygon->apply_force(dt, xf, yf, 0.0, -1.0);
175         universe->update(dt);
176       }
177     }
178
179     {
180       char buffer[1024];
181       sprintf(buffer, "%s/%03d/dyn_%06d_grab.png", dir, n/1000, n);
182       FILE *file = fopen(buffer, "w");
183       grab_trace.write_png(file);
184       fclose(file);
185     }
186   }
187
188   delete universe;
189 }