added file output option
authorNathan Wagner <nw@hydaspes.if.org>
Tue, 7 Apr 2015 20:17:25 +0000 (20:17 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Tue, 7 Apr 2015 20:17:25 +0000 (20:17 +0000)
sim/mkimage [new file with mode: 0755]
sim/sim.c

diff --git a/sim/mkimage b/sim/mkimage
new file mode 100755 (executable)
index 0000000..354a3a2
--- /dev/null
@@ -0,0 +1,155 @@
+#!/usr/bin/env perl
+
+# This program connects to the database and creates one image at a time in a loop
+# It can thus be run in parallel
+
+use strict;
+use warnings;
+
+use JSON;
+use Image::Magick;
+
+my $data = '';
+
+my $forks = 0;
+
+if ($ARGV[0] eq '-f' ) {
+       shift;
+       $forks = shift;
+}
+
+while (<>) {
+       $data .= $_;
+}
+warn "read data\n";
+
+my $json = JSON->new;
+my $run = $json->decode($data);
+
+warn "parsed json\n";
+my %coords;
+
+my (@min, @max); # bounding box so we can know how big to make the image
+
+my $scale = 5;
+
+# get the vertex coordinates for each hex
+if (0) {
+my $i=0;
+foreach my $hex (@{$run->{hexlist}}) {
+       my $c = `./hexverts $scale $hex`;
+       chomp $c;
+       $coords{$hex} = $c;
+       $i++;
+       warn "$i $hex = $c\n";
+}
+} else {
+       %coords = do 'verts.pl';
+}
+#warn keys %coords, "\n";
+
+warn "got coords\n";
+
+my @forks = ();
+if ($forks > 0) {
+       my $elems = @{$run->{gendata}};
+       my $perfork = int($elems / $forks);
+       my $leftover = $elems - $perfork * $forks;
+
+       my $start = 0;
+       for my $fork (0..$forks-1) {
+               $forks[$fork] = { start => $start, end => $start + $perfork-1 };
+               $forks[$fork]{end}++ if $fork < $leftover;
+               $start = $forks[$fork]{end}+1;
+       }
+}
+
+my $forkinfo = join(' ', map { sprintf('[%s %s]', $_->{start}, $_->{end}) } @forks);
+warn "forks = $forkinfo\n";
+
+while (my $f = shift @forks) {
+       my $pid = fork;
+       next if $pid;
+foreach my $gen (@{$run->{gendata}}[$f->{start}..$f->{end}]) {
+       my $image = Image::Magick->new(size => '364x404');
+       $image->ReadImage('canvas:white');
+#      foreach (qw(background fill size colorspace)) {
+#              warn "$_ ", $image->Get($_), "\n";
+#      }
+       
+       my %drawn = ();
+       foreach my $hex (@{$gen->{hexes}}) {
+               my $frac = $hex->{freq}[0]/$hex->{pop}/2.0;
+               my $maxgenfrac = $hex->{pop} / $gen->{maxpop};
+               my @hsv = (
+                       (4.0 / (1.0 + exp(-($frac - 0.5 ))) - 1.5) / 2.0 + 0.075, # hue
+                       1.0, # saturation
+                       0.15+0.85*sqrt($maxgenfrac) # value
+               );
+               for (@hsv) {
+                       $_ = 1.0 if $_ > 1.0;
+                       $_ = 0.0 if $_ < 0.0;
+               }
+
+               my $color = sprintf('hsb(%f%%, %f%%, %f%%)', 100 * $hsv[0], 100 * $hsv[1], 100 * $hsv[2]);
+               #warn "drawing $color\n";
+               die "missing coords for hex ", $hex->{hex}, "\n" unless exists $coords{$hex->{hex}};
+               $image->Draw(fill => $color, primitive=>'polygon', antialias => 1, points => $coords{$hex->{hex}});
+               $drawn{$hex->{hex}} = 1;
+       }
+
+       foreach my $hex (keys %coords) {
+               next if $drawn{$hex};
+               $image->Draw(fill => 'black', primitive=>'polygon', points => $coords{$hex});
+       }
+
+       # make a band on the top for a label
+       # make sure this is a multiple of four, some
+       # of the movie formats require it
+       $image->Splice(geometry => '0x20', background => 'white', gravity => 'North');
+
+        # now annotate the image
+        my $x = 5;   # where to put the annotation
+        my $y = 220;
+       my $font = 'SourceCodePro-Light.ttf';
+       my %params = (
+               font => $font, fill => 'black', stroke => 'black',
+               pointsize => 15, antialias => 1,
+       );
+
+       # set up a title caption
+       #
+       my @lines = (
+               sprintf('gen: %8d', $gen->{gen}),
+               sprintf(q{pop: %8d}, $gen->{pop}),
+               sprintf(q{ybp: %8d}, $gen->{year}),
+       );
+
+       for (@lines) {
+               $image->Annotate(%params, x => $x, y => $y, text => $_);
+               $y += 15;
+       }
+#       $text = sprintf(q{ams: %8d}, $genlen*$gen);
+#      $image->Annotate(x => $x, y => $y, -text => $text); $y += 15;
+
+       my $prefix = $ENV{IMGPREFIX}; 
+       $prefix ||= '';
+
+       my $name = $prefix . sprintf('%04d.png', $gen->{gen});
+       $image->Write($name);
+       warn sprintf("%s gen %d pop %d\n", $name, $gen->{gen}, $gen->{pop});
+}
+exit 0;
+}
+
+while (wait != -1) {};
+
+sub mkdirp {
+       my $path = '.';
+       foreach my $comp (@_) {
+               $path .= "/$comp";
+               mkdir $path unless -d $path;
+               die "can't make director $path: $!" unless -d $path;
+       }
+}
+__END__
index 31a78c76bcee832020f25d297f55cceff971d77f..d0e96695cc584b6bb1f39a8dc339baa772131b66 100644 (file)
--- a/sim/sim.c
+++ b/sim/sim.c
@@ -77,7 +77,7 @@ int main (int ac, char *av[]) {
        clock_gettime(CLOCK_REALTIME, &ts);
        seed = ((unsigned long)(ts.tv_sec) ^ (unsigned long)ts.tv_nsec) & 0xffffffff;
 
-       while ((opt = getopt(ac, av, "r:s:ehp:y:g:m:t:d:")) != -1) {
+       while ((opt = getopt(ac, av, "f:r:s:ehp:y:g:m:t:d:")) != -1) {
                switch (opt) {
                        case 's': seed = atoi(optarg); break;
                        case 'r': run = atoi(optarg); break;
@@ -88,6 +88,11 @@ int main (int ac, char *av[]) {
                        case 'e': eemian = 1; break;
                        case 'h': holocene = 1; break;
                        case 'p': setpopstr(map, optarg); defaultpop = 0;break;
+                       case 'f': if (freopen(optarg, "w", stdout) == NULL) {
+                                         perror("sim");
+                                         exit(EXIT_FAILURE);
+                                 }
+                                 break;
                        default:
                                  fprintf(stderr, "Usage: %s [-s seed] [-r run] [-y startyear] [-eh] [-p hex:freq,freq[:freq,freq...]\n",
                                                  av[0]);
@@ -129,7 +134,7 @@ int main (int ac, char *av[]) {
 
        printf("{");
        printf(" \"run\": %d, \"seed\": %d, \"gens\": %d", run, seed, gens);
-       printf(",\n\"options\": { \"capfactor\": %f }", capfactor);
+       printf(",\n\"options\": { \"capfactor\": %g }", capfactor);
        printf(",\n\"gendata\": [\n");
 
        dumpgenjson(map, 0, year);