Update.
[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
22 using namespace std;
23
24 #include "misc.h"
25 #include "task.h"
26 #include "simple_window.h"
27 #include "universe.h"
28 #include "plotter.h"
29 #include "retina.h"
30 #include "manipulator.h"
31 #include "intelligence.h"
32 #include "canvas_cairo.h"
33
34 void generate_png(Universe *universe, scalar_t scale, FILE *file) {
35   CanvasCairo canvas(scale, universe->width(), universe->height());
36   canvas.set_line_width(2.0);
37   universe->draw(&canvas);
38   canvas.write_png(file);
39 }
40
41 int main(int argc, char **argv) {
42   scalar_t world_width = 400;
43   scalar_t world_height = 400;
44   scalar_t grab_start_x = world_width * 0.5;
45   scalar_t grab_start_y = world_height * 0.75;
46
47   Universe *universe;
48   Polygon *grabbed_polygon;
49
50   if(argc < 2 || argc > 3) {
51     cerr << argv[0] << " <nb pairs to generate> [<dir> [<seed>]]" << endl;
52     exit(1);
53   }
54
55   int nb_pairs = atoi(argv[1]);
56
57   char dir[1024] = "/tmp/";
58
59   if(argc > 2) {
60     strncpy(dir, argv[2], sizeof(dir) / sizeof(char) - 1);
61   }
62
63   if(argc > 3) {
64     srand48(atoi(argv[1]));
65   }
66
67   universe = new Universe(10, world_width, world_height);
68
69   for(int n = 0; n < nb_pairs; n++) {
70     cout << "Example " << n << endl;
71
72     do {
73       universe->clear();
74
75       const int nb_attempts_max = 100;
76       int nb_attempts = 0;
77
78       for(int u = 0; u < 10; u++) {
79         Polygon *pol = 0;
80
81         nb_attempts = 0;
82
83         do {
84           scalar_t square_size = 80;
85
86           scalar_t x[] = {
87             - square_size * 0.5,
88             + square_size * 0.5,
89             + square_size * 0.5,
90             - square_size * 0.5,
91           };
92
93           scalar_t y[] = {
94             - square_size * 0.5,
95             - square_size * 0.5,
96             + square_size * 0.5,
97             + square_size * 0.5,
98           };
99
100           scalar_t delta = square_size / sqrt(2.0);
101           scalar_t object_center_x = delta + (world_width - 2 * delta) * drand48();
102           scalar_t object_center_y = delta + (world_height - 2 * delta) * drand48();
103           scalar_t red, green, blue;
104           red = 0.90;
105           green = red;
106           blue = red;
107           delete pol;
108           pol = new Polygon(0.5,
109                             red, green, blue,
110                             x, y, sizeof(x)/sizeof(scalar_t));
111           pol->set_position(object_center_x, object_center_y, M_PI * 2 * drand48());
112           pol->set_speed(0, 0, 0);
113           universe->initialize_polygon(pol);
114           nb_attempts++;
115         } while(nb_attempts < nb_attempts_max && universe->collide(pol));
116
117         if(nb_attempts == nb_attempts_max) {
118           delete pol;
119           u = 0;
120           universe->clear();
121           nb_attempts = 0;
122         } else {
123           universe->add_polygon(pol);
124         }
125       }
126
127       grabbed_polygon = universe->pick_polygon(grab_start_x, grab_start_y);
128     } while(!grabbed_polygon);
129
130     const scalar_t scaling = 0.16;
131
132     CanvasCairo grab_trace(scaling, world_width, world_height);
133
134     {
135       char buffer[1024];
136       sprintf(buffer, "%s/dyn_%06d_world_0.png", dir, n);
137       FILE *file = fopen(buffer, "w");
138       generate_png(universe, scaling, file);
139       fclose(file);
140     }
141
142     scalar_t grab_relative_x = grabbed_polygon->relative_x(grab_start_x, grab_start_y);
143     scalar_t grab_relative_y = grabbed_polygon->relative_y(grab_start_x, grab_start_y);
144     // scalar_t grab_previous_x = grab_start_x, grab_previous_y = grab_start_y;
145
146     {
147       int n = 36;
148       scalar_t xp[n], yp[n];
149       for(int k = 0; k < n; k++) {
150         scalar_t radius = 1/scaling;
151         scalar_t alpha = 2 * M_PI * scalar_t(k) / scalar_t(n);
152         xp[k] = grab_start_x + radius * cos(alpha);
153         yp[k] = grab_start_y + radius * sin(alpha);
154       }
155       grab_trace.set_drawing_color(0.0, 0.0, 0.0);
156       grab_trace.set_line_width(1.0);
157       grab_trace.draw_polygon(1, n, xp, yp);
158     }
159
160     const int nb_iterations = 250;
161     scalar_t dt = 0.1;
162     for(int i = 0; i < nb_iterations; i++) {
163       scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y);
164       scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y);
165       grabbed_polygon->apply_force(dt, xf, yf, 0.0, -1.0);
166       universe->update(dt);
167
168       /*
169         {
170         scalar_t xp[2], yp[2];
171         xp[0] = grab_previous_x;
172         yp[0] = grab_previous_y;
173         xp[1] = xf;
174         yp[1] = yf;
175         grab_previous_x = xf;
176         grab_previous_y = yf;
177
178         grab_trace.set_drawing_color(0.0, 0.0, 0.0);
179         grab_trace.draw_polygon(1, 2, xp, yp);
180         }
181       */
182     }
183
184     {
185       char buffer[1024];
186       sprintf(buffer, "%s/dyn_%06d_world_1.png", dir, n);
187       FILE *file = fopen(buffer, "w");
188       generate_png(universe, scaling, file);
189       fclose(file);
190     }
191
192     {
193       char buffer[1024];
194       sprintf(buffer, "%s/dyn_%06d_grab.png", dir, n);
195       FILE *file = fopen(buffer, "w");
196       grab_trace.write_png(file);
197       fclose(file);
198     }
199   }
200
201   delete universe;
202 }