#include #include #include #include "gene.h" #define NColors 128 static int ImapSize = 5; static unsigned long pixel[NColors]; static Window window; static Pixmap pmap,backmap,ipmap; static unsigned int width, height; extern Display *dpy; extern int scr; extern GC gc; extern short short_int_value(); static double dfitness(x, y) double x, y; { return (cos((x+y)*5)+cos((x-y)*5)+2)/(hypot(x,y)*0.2+1.0)/4.0; } double fitness(g) gene *g; { return dfitness((double)short_int_value(g->x)/(MAXVALUE+1), (double)short_int_value(g->y)/(MAXVALUE+1)); } redisplay(e) XExposeEvent *e; { XCopyArea(dpy,backmap,window,gc,e->x,e->y, e->width,e->height,e->x,e->y); } gene *random_gene() { static gene new; new.x = (short)(lrand48() & 0xffff); new.y = (short)(lrand48() & 0xffff); return &new; } static void set_colors() { Colormap cmap; XColor ac; int i, j, s, e; float r1,g1,b1, r2,g2,b2; static struct { float r, g, b, p; } d[] = { { 0.0, 0.0, 0.2, 0.15}, /* blue black */ { 0.0, 0.0, 1.0, 0.10}, /* blue */ { 0.0, 0.7, 1.0, 0.10}, { 0.0, 1.0, 1.0, 0.10}, /* cyan */ { 0.0, 1.0, 0.7, 0.10}, { 0.0, 1.0, 0.0, 0.10}, /* green */ { 0.7, 1.0, 0.0, 0.10}, { 1.0, 1.0, 0.0, 0.10}, /* yellow */ { 0.8, 0.7, 0.05, 0.15}, { 0.6, 0.16, 0.16, 999.} /* brown */ }; cmap = DefaultColormap(dpy,scr); ac.flags = DoRed | DoGreen | DoBlue; for (j = e = 0; e < NColors; j ++) { r1 = d[j].r; g1 = d[j].g; b1 = d[j].b; r2 = d[j+1].r; g2 = d[j+1].g; b2 = d[j+1].b; s = e; if (d[j+1].p > 1.) e = NColors; else e += NColors * d[j].p; for (i = s; i < e && i < NColors; i ++) { ac.red = (r1 + (i-s)*(r2-r1)/(e-s)) * 65535; ac.green = (g1 + (i-s)*(g2-g1)/(e-s)) * 65535; ac.blue = (b1 + (i-s)*(b2-b1)/(e-s)) * 65535; if (!XAllocColor(dpy, cmap, &ac)) { fprintf(stderr,"cannot allocate enough number of colors (%d/%d).\n", i,NColors); exit(1); } pixel[i] = ac.pixel; } } } domain_init(win) Window win; { Window root; int x, y, k, j; unsigned int border, depth, bpp; char *dp; XImage *xip; Visual *visual = DefaultVisual(dpy,scr); set_colors(); window = win; XGetGeometry(dpy,window,&root,&x,&y,&width,&height,&border,&depth); if (depth < 8) { fprintf(stderr,"Sorry, this program works only on depth >= 8.\n"); exit(1); } bpp = (depth <= 8)? 1 : ((depth <= 16)? 2 : 4); pmap = XCreatePixmap(dpy,window,width,height,depth); backmap = XCreatePixmap(dpy,window,width,height,depth); ImapSize = width / 100; if (ImapSize & 1 == 0) ImapSize ++; ipmap = XCreatePixmap(dpy,window,ImapSize,ImapSize,depth); XSetForeground(dpy,gc,WhitePixel(dpy,scr)); XFillRectangle(dpy,ipmap,gc,0,0,ImapSize,ImapSize); XSetForeground(dpy,gc,BlackPixel(dpy,scr)); XDrawRectangle(dpy,ipmap,gc,0,0,ImapSize-1,ImapSize-1); if (!(dp = (char *)malloc(width * height * bpp))) { perror("Image memory"); exit(1); } xip = XCreateImage(dpy,visual,depth,ZPixmap, 0,dp,width,height,8,width * bpp); for (y = 0; y < height; y ++) for (x = 0; x < width; x ++) { k = dfitness((double)x/width*2.-1.,(double)y/height*2.-1.) * NColors; if (k < 0) k = 0; else if (k >= NColors) k = NColors - 1; switch (bpp) { case 1: dp[y*width+x] = (char)pixel[k]; break; case 2: j = (y*width+x)*2; dp[j] = pixel[k] & 0xff; dp[j+1] = (pixel[k] >> 8) & 0xff; } } XPutImage(dpy,pmap,gc,xip,0,0,0,0,width,height); XDestroyImage(xip); } static void show_individual(g,data) gene *g; void *data; { int x = ((int)short_int_value(g->x)+MAXVALUE+1)*width/((MAXVALUE+1)*2)-1, y = ((int)short_int_value(g->y)+MAXVALUE+1)*height/((MAXVALUE+1)*2)-1; XCopyArea(dpy,ipmap,backmap,gc,0,0,ImapSize,ImapSize, x-ImapSize/2,y-ImapSize/2); } domain_draw() { XCopyArea(dpy,pmap,backmap,gc,0,0,width,height,0,0); forall_gene(show_individual,NULL); XCopyArea(dpy,backmap,window,gc,0,0,width,height,0,0); } fitness_string(value,str) double value; char *str; { sprintf(str,"%.3f",value); }