/* bomb - automatic interactive visual stimulation Copyright (C) 1994 Scott Draves This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "image.h" /* simple hill climber, circular topology */ int dist(Pixel p0, Pixel p1) { int d; int r; d = p0.r - p1.r; r = d * d; d = p0.g - p1.g; r += d * d; d = p0.b - p1.b; r += d * d; return r; } double total_length(Pixel *cmap, int n) { int i; double t = dist(cmap[0], cmap[n-1]); for (i = 1; i < n; i++) t += dist(cmap[i-1], cmap[i]); return t / 1000.0; } void improve_cmap_order(Pixel *cmap, int n) { int i, i0, i1, niters; int total_d = 0; Pixel t; niters = argd("niters", 100) * 200000; for (i = 0; i < niters; i++) { int as_is, swapped; i0 = R%n; i1 = R%n; as_is = (dist(cmap[(i0-1)%n], cmap[i0]) + dist(cmap[i0], cmap[(i0+1)%n]) + dist(cmap[(i1-1)%n], cmap[i1]) + dist(cmap[i1], cmap[(i1+1)%n])); swapped = (dist(cmap[(i0-1)%n], cmap[i1]) + dist(cmap[i1], cmap[(i0+1)%n]) + dist(cmap[(i1-1)%n], cmap[i0]) + dist(cmap[i0], cmap[(i1+1)%n])); if (swapped < as_is) { total_d += as_is - swapped; if (total_d > 20000) { total_d = 0; fprintf(stderr, "."); } t = cmap[i0]; cmap[i0] = cmap[i1]; cmap[i1] = t; } } fprintf(stderr, "\n"); } int main(int argc, char **argv) { char *fname = args("in", "in.ppm"); int nentries = argd("nentries", 256); int box_size = argd("box_size", 4); Pixel *cmap = malloc(sizeof(Pixel) * nentries); int t, i; Image in; Image box; image_init(&in); image_init(&box); if (NULL == cmap) { fprintf(stderr, "could not allocate %d entry cmap\n", nentries); exit(1); } if (TCL_ERROR == image_read(&in, fname)) exit(1); t = time(NULL); srandom(argd("seed", t)); for (i = 0; i < nentries; i++) { Pixel p; image_random_tile(&box, &in, box_size); image_mean_pixel(&box, &p); cmap[i] = p; } fprintf(stderr, "length = %g\n", total_length(cmap, nentries)); improve_cmap_order(cmap, nentries); fprintf(stderr, "length = %g\n", total_length(cmap, nentries)); printf("(comment %s)\n(cmap\n", fname); for (i = 0; i < nentries; i++) { printf(" (%d %d %d)", cmap[i].r, cmap[i].g, cmap[i].b); if (3 == i%4) printf("\n"); } printf(")\n"); }