X-Git-Url: https://www.fleuret.org/cgi-bin/gitweb/gitweb.cgi?p=dyncnn.git;a=blobdiff_plain;f=flatland.cc;h=3a59e88d089ade1e1f96a485c6bfa60f4df25dd9;hp=c27bd979373dcaf03692dee3ab035a8659d754fb;hb=fe5dee151313b6abd8ffee2c5fc5593f326e663f;hpb=be0c7d53f21ce96c70e7c13ef0ba2c9eca10ca23 diff --git a/flatland.cc b/flatland.cc index c27bd97..3a59e88 100644 --- a/flatland.cc +++ b/flatland.cc @@ -38,13 +38,6 @@ using namespace std; #include "universe.h" #include "canvas_cairo.h" -void generate_png(Universe *universe, scalar_t scale, FILE *file) { - CanvasCairo canvas(scale, universe->width(), universe->height()); - canvas.set_line_width(1.0 / scale); - universe->draw(&canvas); - canvas.write_png(file); -} - FILE *safe_fopen(const char *name, const char *mode) { FILE *file = fopen(name, mode); if(!file) { @@ -59,34 +52,59 @@ void print_help(const char *command) { exit(1); } +////////////////////////////////////////////////////////////////////// + +void draw_universe_on_canvas(CanvasCairo *canvas, scalar_t scaling, + Universe *universe) { + canvas->set_line_width(1.0 / scaling); + universe->draw(canvas); +} + +void draw_grabbing_point_on_canvas(CanvasCairo *canvas, scalar_t scaling, + scalar_t xg, scalar_t yg, + scalar_t r, scalar_t g, scalar_t b) { + scalar_t radius = 1/scaling; + int n = 36; + scalar_t xp[n], yp[n]; + for(int k = 0; k < n; k++) { + scalar_t alpha = 2 * M_PI * scalar_t(k) / scalar_t(n); + xp[k] = xg + radius * cos(alpha); + yp[k] = yg + radius * sin(alpha); + } + canvas->set_drawing_color(r, g, b); + canvas->set_line_width(2.0); + canvas->draw_polygon(1, n, xp, yp); +} + +////////////////////////////////////////////////////////////////////// + int main(int argc, char **argv) { const scalar_t world_width = 400; const scalar_t world_height = 400; - const scalar_t block_size = 80; + const scalar_t scaling = 0.16; // So that 400 * 0.16 = 64 + const scalar_t shape_size = 80; const scalar_t dt = 0.1; - const int nb_iterations_per_steps = 20; + const int nb_iterations_per_steps = 5; ////////////////////////////////////////////////////////////////////// - // We will generate images { 0, every_nth, 2 * every_nth, ..., nb_frames - 1 } + // We will generate images { 0, every_nth, 2 * every_nth, ..., k * every_nth < nb_frames } // The framerate every_nth may be set to smaller value to generate // nice materials for presentations or papers. int every_nth = 4; - int nb_frames = 5; - int multi_grasp = 0; int nb_shapes = 1; char data_dir[1024] = "/tmp/"; + int multi_images = 0; + int show_grabbing_point = 0; + int skip = -1; ////////////////////////////////////////////////////////////////////// - Universe *universe; - Polygon *grabbed_polygon; - if(argc < 2) { print_help(argv[0]); } @@ -135,6 +153,23 @@ int main(int argc, char **argv) { i++; } + else if(strcmp(argv[i], "--multi_images") == 0) { + multi_images = 1; + i++; + } + + else if(strcmp(argv[i], "--show_grabbing_point") == 0) { + show_grabbing_point = 1; + i++; + } + + else if(strcmp(argv[i], "--skip") == 0) { + i++; + if(i == argc) { print_help(argv[0]);} + skip = atoi(argv[i]); + i++; + } + else { cerr << "Unknown option " << argv[i] << "." << endl; abort(); @@ -151,16 +186,29 @@ int main(int argc, char **argv) { abort(); } - universe = new Universe(nb_shapes, world_width, world_height); - for(int n = 0; n < nb_sequences; n++) { - scalar_t grab_start_x = world_width * 0.5; - scalar_t grab_start_y = world_height * 0.75; + Universe *universe; + Polygon *grabbed_polygon; + + universe = new Universe(nb_shapes, world_width, world_height); + + const int nb_saved_frames = (nb_frames + every_nth - 1) / every_nth; + + CanvasCairo *canvases[nb_saved_frames * 2]; + + for(int s = 0; s < 2 * nb_saved_frames; s++) { + canvases[s] = new CanvasCairo(scaling, universe->width(), universe->height()); + } + + scalar_t grab_start_x, grab_start_y; if(multi_grasp) { grab_start_x = world_width * (0.1 + 0.8 * drand48()); grab_start_y = world_height * (0.1 + 0.8 * drand48()); + } else { + grab_start_x = world_width * 0.5; + grab_start_y = world_height * 0.75; } if((n+1)%100 == 0) { @@ -182,40 +230,30 @@ int main(int argc, char **argv) { nb_attempts = 0; do { - scalar_t x[] = { - - block_size * 0.4, - + block_size * 0.4, - + block_size * 0.4, - - block_size * 0.4, - }; - - scalar_t y[] = { - - block_size * 0.6, - - block_size * 0.6, - + block_size * 0.6, - + block_size * 0.6, - }; - - scalar_t delta = block_size / sqrt(2.0); + scalar_t x[] = { - shape_size * 0.4, + shape_size * 0.4, + + shape_size * 0.4, - shape_size * 0.4 }; + + scalar_t y[] = { - shape_size * 0.6, - shape_size * 0.6, + + shape_size * 0.6, + shape_size * 0.6 }; + + scalar_t delta = shape_size / sqrt(2.0); + scalar_t object_center_x = delta + (world_width - 2 * delta) * drand48(); scalar_t object_center_y = delta + (world_height - 2 * delta) * drand48(); - scalar_t red, green, blue; - red = 1.00; - green = red; - blue = red; + delete pol; - pol = new Polygon(0.5, - red, green, blue, - x, y, sizeof(x)/sizeof(scalar_t)); + pol = new Polygon(0.5, 1.0, 1.0, 1.0, x, y, sizeof(x)/sizeof(scalar_t)); pol->set_position(object_center_x, object_center_y, M_PI * 2 * drand48()); pol->set_speed(0, 0, 0); + universe->initialize_polygon(pol); + nb_attempts++; } while(nb_attempts < nb_attempts_max && universe->collide(pol)); if(nb_attempts == nb_attempts_max) { delete pol; - u = 0; + u = -1; universe->clear(); nb_attempts = 0; } else { @@ -226,58 +264,73 @@ int main(int argc, char **argv) { grabbed_polygon = universe->pick_polygon(grab_start_x, grab_start_y); } while(!grabbed_polygon); - const scalar_t scaling = 0.16; - - CanvasCairo grab_trace(scaling, world_width, world_height); - - { + if(n%1000 == 0) { char buffer[1024]; - sprintf(buffer, "%s/%03d/", data_dir, n/1000); + sprintf(buffer, "%s/%03d/", data_dir, n / 1000); mkdir(buffer, 0777); } - scalar_t grab_relative_x = grabbed_polygon->relative_x(grab_start_x, grab_start_y); - scalar_t grab_relative_y = grabbed_polygon->relative_y(grab_start_x, grab_start_y); - - { - int n = 36; - scalar_t xp[n], yp[n]; - for(int k = 0; k < n; k++) { - scalar_t radius = 1/scaling; - scalar_t alpha = 2 * M_PI * scalar_t(k) / scalar_t(n); - xp[k] = grab_start_x + radius * cos(alpha); - yp[k] = grab_start_y + radius * sin(alpha); + if(skip < 0 || n >= skip) { + + scalar_t grab_relative_x = grabbed_polygon->relative_x(grab_start_x, grab_start_y); + scalar_t grab_relative_y = grabbed_polygon->relative_y(grab_start_x, grab_start_y); + + for(int s = 0; s < nb_frames; s++) { + if(s % every_nth == 0) { + int t = s / every_nth; + scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y); + scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y); + + canvases[2 * t + 0]->clear(); + draw_grabbing_point_on_canvas(canvases[2 * t + 0], scaling, + xf, yf, 0.0, 0.0, 0.0); + canvases[2 * t + 1]->clear(); + draw_universe_on_canvas(canvases[2 * t + 1], scaling, universe); + + if(show_grabbing_point) { + draw_grabbing_point_on_canvas(canvases[2 * t + 1], scaling, + xf, yf, 1.0, 0.0, 0.0); + } + } + + if(s < nb_frames - 1) { + // Run the simulation + for(int i = 0; i < nb_iterations_per_steps; i++) { + scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y); + scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y); + grabbed_polygon->apply_force(dt, xf, yf, 0.0, -1.0); + universe->update(dt); + } + } } - grab_trace.set_drawing_color(0.0, 0.0, 0.0); - grab_trace.set_line_width(2.0); - grab_trace.draw_polygon(1, n, xp, yp); - } - for(int s = 0; s < nb_frames; s++) { - if(s % every_nth == 0) { - char buffer[1024]; - sprintf(buffer, "%s/%03d/dyn_%06d_world_%03d.png", data_dir, n/1000, n, s); + char buffer[1024]; + + if(multi_images) { + for(int j = 0; j < nb_saved_frames; j++) { + FILE *file; + sprintf(buffer, "%s/%03d/dyn_%06d_grab_%02d.png", data_dir, n / 1000, n, j); + file = safe_fopen(buffer, "w"); + canvases[j * 2 + 0]->write_png(file); + fclose(file); + sprintf(buffer, "%s/%03d/dyn_%06d_state_%02d.png", data_dir, n / 1000, n, j); + file = safe_fopen(buffer, "w"); + canvases[j * 2 + 1]->write_png(file); + fclose(file); + } + } else { + CanvasCairo main_canvas(scaling, nb_saved_frames, 2, canvases); + sprintf(buffer, "%s/%03d/dyn_%06d.png", data_dir, n / 1000, n); FILE *file = safe_fopen(buffer, "w"); - generate_png(universe, scaling, file); + main_canvas.write_png(file); fclose(file); } - - for(int i = 0; i < nb_iterations_per_steps; i++) { - scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y); - scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y); - grabbed_polygon->apply_force(dt, xf, yf, 0.0, -1.0); - universe->update(dt); - } } - { - char buffer[1024]; - sprintf(buffer, "%s/%03d/dyn_%06d_grab.png", data_dir, n/1000, n); - FILE *file = safe_fopen(buffer, "w"); - grab_trace.write_png(file); - fclose(file); + for(int t = 0; t < 2 * nb_saved_frames; t++) { + delete canvases[t]; } - } - delete universe; + delete universe; + } }