#include #include #include #include #include "gene.h" #define MaxObjects 0x20000 static Drawable Canvas; static int NColumns,IndWidth,IndHeight; static int NObject; static struct obj_buf { double z; Cell *c; } ObjectBuffer[MaxObjects]; static double vx = 0, vy = 0, vz = 5.0; /* view position */ static double rx, ry, rz; /* rotation */ static double sinrx,cosrx,sinry,cosry,sinrz,cosrz; /* sin & cos of vr */ static double scale; static int CenterX, CenterY; static unsigned char ZoomMode = 0; static Individual *ZoomedIndividual; extern int PopulationSize; extern Individual *Population; extern unsigned long Step; extern double CellSize; extern int WorldWidth, WorldHeight; extern Display *dpy; extern Window win; extern int screen, depth; extern GC gc; extern unsigned long fg, bg; #define COLOR_GRADES 8 #define NCELLSTATES 16 #define NCOLORS (COLOR_GRADES*NCELLSTATES) static struct { int red, green, blue; } CellColors[] = { {138,164,255},{109,206,255},{93,243,255},{98,255,228}, {131,255,172},{183,255,123},{228,255,98},{255,255,90}, {255,224,100},{255,192,117},{255,167,136},{255,141,161}, {255,105,213},{255,89,255},{207,108,255},{163,139,255} }; unsigned long pixel[NCOLORS]; double radius_rate[COLOR_GRADES]; draw_init() { XColor acolor[NCOLORS], *cp; int pl[1], i, j, k; Colormap cmap = DefaultColormap(dpy,screen); extern int IScale; if (!XAllocColorCells(dpy, cmap, True, pl, 0, pixel, NCOLORS)) { fprintf(stderr,"Sorry, there is no enough room to allocate color maps.\n"); exit(1); } for (i = k = 0, cp = acolor; i < NCELLSTATES; i ++) { for (j = 1; j <= COLOR_GRADES; j ++, k ++, cp ++) { cp->pixel = pixel[k]; cp->flags = DoRed | DoGreen | DoBlue; cp->red = (CellColors[i].red * j * 255)/ COLOR_GRADES; cp->green = (CellColors[i].green * j * 255) / COLOR_GRADES; cp->blue = (CellColors[i].blue * j * 255) / COLOR_GRADES; } } XStoreColors(dpy, cmap, acolor, NCOLORS); for (i = 0; i < COLOR_GRADES; i ++) radius_rate[i] = sin((COLOR_GRADES-i)*M_PI/(2*COLOR_GRADES)); NColumns = ceil(sqrt((double)PopulationSize)); IndWidth = WorldWidth / NColumns; IndHeight = WorldHeight / NColumns; Canvas = XCreatePixmap(dpy,win,WorldWidth,WorldHeight,depth); if (!Canvas) { fprintf(stderr,"Sorry, cannot create pixmap.\n"); Canvas = win; } XSetLineAttributes(dpy,gc,5,LineSolid,CapNotLast,JoinMiter); } static void draw_sphere(p) struct obj_buf *p; { unsigned long *pxl; Cell *c = p->c; int i, d; double r; extern unsigned char WireFrameMode, BlackBackground; pxl = pixel + (c->step % NCELLSTATES) * COLOR_GRADES; if (WireFrameMode) { XSetForeground(dpy,gc, pxl[BlackBackground?COLOR_GRADES-1:COLOR_GRADES/2]); if (c->mother) XDrawLine(dpy,Canvas,gc, (int)(c->draw_x),(int)(c->draw_y), (int)(c->mother->draw_x),(int)(c->mother->draw_y)); else XDrawPoint(dpy,Canvas,gc, (int)(c->draw_x),(int)(c->draw_y)); } else for (i = 0; i < COLOR_GRADES; i ++) { XSetForeground(dpy,gc,pxl[i]); r = c->draw_r * radius_rate[i] * 1.1; d = r + r; XFillArc(dpy,Canvas,gc, (int)(c->draw_x - r),(int)(c->draw_y - r),d,d,0,64*360); } } static void draw_cell(c) Cell *c; { double x = c->x, y = c->y, z = c->z, r = CellSize; double p,q,s,zz; if (c->step > Step) return; if (NObject == MaxObjects) { /* fprintf(stderr,"Too many cells: %d\n",NObject); */ return; } p = y * cosrz - x * sinrz; q = y * sinrz + x * cosrz; y = p; x = q; p = x * cosry - z * sinry; q = x * sinry + z * cosry; x = p; z = q; p = z * cosrx - y * sinrx; q = z * sinrx + y * cosrx; z = p; y = q; x += vx; y += vy; z += vz; if (z < 1e-20) return; s = scale / z; c->draw_x = CenterX + x * s; c->draw_y = CenterY - y * s; c->draw_r = r * s / sqrt(1.0 - r * r / z * z); ObjectBuffer[NObject].z = z; ObjectBuffer[NObject].c = c; NObject ++; } static int comp_zz(a,b) struct obj_buf *a, *b; { return (a->z < b->z)? 1 : ((a->z > b->z)? -1 : 0); } static void draw_individual(ind) Individual *ind; { struct obj_buf *p; NObject = 0; for_all_cells(ind,draw_cell); qsort(ObjectBuffer,NObject,sizeof(struct obj_buf),comp_zz); for (p = ObjectBuffer; NObject > 0; NObject --, p ++) draw_sphere(p); } Individual *get_pointed_individual(x,y) int x,y; { int i = (y / IndHeight) * NColumns + (x / IndWidth); if (i >= PopulationSize) return NULL; return (Population + i); } switch_draw_mode(x,y) int x,y; { if (ZoomMode) { ZoomMode = 0; redraw_world(); } else if (ZoomedIndividual = get_pointed_individual(x,y)) { ZoomMode = 1; redraw_world(); } } static double distance(a,b) Cell *a, *b; { return (!a || !b)? 0.0 : sqrt(pow(a->x-b->x,2.0)+pow(a->y-b->y,2.0)+pow(a->z-b->z,2.0)); } static void print_cell(c) Cell *c; { printf("%x(%x):%d,%x(%g,%g,%g),%g\n", c,c->mother,c->step,c->state,c->x,c->y,c->z, distance(c->mother,c)); } show_individual(x,y) int x,y; { Individual *ind; Cell *c; int i; if (ZoomMode) ind = ZoomedIndividual; else if (!(ind = get_pointed_individual(x,y))) return 0; printf("--------------- Individual #%d, score = %d -----------\n", ind->id,fitness(ind)); for (i = 0; i < GeneLen; i++) printf("%x:",ind->gene[i]); putchar('\n'); for_all_cells(ind,print_cell); } redraw_world() { Individual *ind; int i; extern int GenerationLength; XSetForeground(dpy,gc,bg); XFillRectangle(dpy,Canvas,gc,0,0,WorldWidth,WorldHeight); rx = M_PI / 6; ry = Step * M_PI * 2 / GenerationLength; rz = 0; sinrx = sin(rx); cosrx = cos(rx); sinry = sin(ry); cosry = cos(ry); sinrz = sin(rz); cosrz = cos(rz); if (ZoomMode) { scale = WorldWidth * IScale * 0.01; CenterX = WorldWidth / 2; CenterY = WorldHeight / 2; draw_individual(ZoomedIndividual); } else { scale = IndWidth * IScale * 0.01; for (ind = Population, i = 0; i < PopulationSize; i ++, ind ++) { CenterX = IndWidth / 2 + (i % NColumns) * IndWidth; CenterY = IndHeight / 2 + (i / NColumns) * IndHeight; draw_individual(ind); } } if (Canvas != win) XCopyArea(dpy,Canvas,win,gc,0,0,WorldWidth,WorldHeight,0,0); XFlush(dpy); } redisplay_world() { if (Canvas == win) redraw_world(); else XCopyArea(dpy,Canvas,win,gc,0,0,WorldWidth,WorldHeight,0,0); } dump_screen() { extern char *DumpFileName; static FILE *out = NULL; XImage *image; image = XGetImage(dpy,Canvas,0,0,WorldWidth,WorldHeight,-1,ZPixmap); if (!out) { XWDFileHeader h; XWDColor xwdcol[NCOLORS+2]; XColor xcol[NCOLORS+2]; int i; if (!(out = fopen(DumpFileName,"w"))) { fprintf(stderr,"%s: cannot open.\n",DumpFileName); return 0; } ximage_to_xwdhead(image,&h); fwrite(&h,sizeof(h),1,out); for (i = 0; i < NCOLORS; i ++) xcol[i].pixel = pixel[i]; xcol[NCOLORS].pixel = fg; xcol[NCOLORS+1].pixel = bg; for (i = 0; i < NCOLORS+2; i ++) xcol[i].flags = DoRed | DoGreen | DoBlue; XQueryColors(dpy,DefaultColormap(dpy,screen), xcol,NCOLORS+2); for (i = 0; i < NCOLORS+2; i ++) { xwdcol[i].pixel = xcol[i].pixel; xwdcol[i].red = xcol[i].red; xwdcol[i].green = xcol[i].green; xwdcol[i].blue = xcol[i].blue; xwdcol[i].flags = xcol[i].flags; } fwrite(xwdcol,sizeof(XWDColor),NCOLORS+2,out); } fwrite(image->data,1,image->bytes_per_line*image->height,out); XDestroyImage(image); } ximage_to_xwdhead(i,h) XImage *i; XWDFileHeader *h; { h->header_size = sizeof(XWDFileHeader); h->file_version = XWD_FILE_VERSION; h->pixmap_format = ZPixmap; h->pixmap_depth = depth; h->pixmap_width = WorldWidth; h->pixmap_height = WorldHeight; h->xoffset = i->xoffset; h->byte_order = i->byte_order; h->bitmap_unit = i->bitmap_unit; h->bitmap_bit_order = i->bitmap_bit_order; h->bitmap_pad = i->bitmap_pad; h->bits_per_pixel = i->bits_per_pixel; h->bytes_per_line = i->bytes_per_line; /* h->visual_class = */ h->red_mask = i->red_mask; h->green_mask = i->green_mask; h->blue_mask = i->blue_mask; /* h->bits_per_rgb = */ /* h->colormap_entries = */ h->ncolors = NCOLORS + 2; h->window_width = WorldWidth; h->window_height = WorldHeight; }