Index: Makefile =================================================================== --- Makefile (revision 7398) +++ Makefile (revision 7399) @@ -1,5 +1,11 @@ -CFLAGS = -Wall -g -O3 +CFLAGS = -Wall -g +# -O3 LDFLAGS = -lm -find_line_indep: find_line_indep.o pcb_draw.o gp.o c24lib/image/draw.o c24lib/image/image.o c24lib/image/pnm.o +LIBS=pcb_draw.o gp.o c24lib/image/draw.o c24lib/image/image.o c24lib/image/pnm.o + +find_polyl: find_polyl.o $(LIBS) + +find_line_indep: find_line_indep.o $(LIBS) + find_line_indep.o: pcb_common.h gp.h Index: find_line_indep.c =================================================================== --- find_line_indep.c (revision 7398) +++ find_line_indep.c (revision 7399) @@ -31,6 +31,19 @@ #include "pcb_common.h" +static inline int pcb_num_strokes(pcb_t *p) +{ + return p->len; +} + +static void pcb_dump_str(FILE *f, pcb_t *p) +{ + int n; + for(n = 0; n < p->len; n++) + fprintf(f,"stroke %d %d %d %d %d\n", p->str[n].x1, p->str[n].y1, p->str[n].x2, p->str[n].y2, p->str[n].th); +} + + static inline void pcb_draw(image_t *img, pcb_t *p) { int n; Index: find_polyl.c =================================================================== --- find_polyl.c (nonexistent) +++ find_polyl.c (revision 7399) @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include +#include "c24lib/image/image.h" +#include "c24lib/image/draw.h" +#include "c24lib/image/pnm.h" + +#include "pcb_draw.h" +#include "gp.h" + +#define DUMPDIR "/tmp/gpstroke/" + +#define STROKE_PENALTY 550 +#define MAX_TH 12 +#define MIN_TH 8 + +#define MAX_STROKES 16 +#define MAX_POLYS 3 +int max_strokes = 16; +image_t *ref, *canvas; + +typedef struct { + int x, y; +} point_t; + +typedef struct { + int len; + point_t pt[MAX_STROKES]; + int th; +} polyline_t; + +typedef struct { + polyline_t poly[MAX_POLYS]; +} pcb_t; + +#include "pcb_common.h" + +static inline int pcb_num_strokes(pcb_t *p) +{ + int pi, res = 0; + for(pi = 0; pi < MAX_POLYS; pi++) + res += p->poly[pi].len; + return res; +} + +static void pcb_dump_str(FILE *f, pcb_t *p) +{ + int n, pi; + for(pi = 0; pi < MAX_POLYS; pi++) { + polyline_t *P = &p->poly[pi]; + if (pi > 0) + fprintf(f, "\n"); + for(n = 1; n < P->len; n++) { + fprintf(f,"stroke %d %d %d %d %d\n", P->pt[n-1].x, P->pt[n-1].y, P->pt[n].x, P->pt[n].y, clamp(P->th, MIN_TH, MAX_TH)); + } + } +} + + +static inline void pcb_draw(image_t *img, pcb_t *p) +{ + int n, pi; + + draw_color(pixel_black); + for(pi = 0; pi < MAX_POLYS; pi++) { + polyline_t *P = &p->poly[pi]; + for(n = 1; n < P->len; n++) + draw_pcb_line(img, P->pt[n-1].x, P->pt[n-1].y, P->pt[n].x, P->pt[n].y, clamp(P->th, MIN_TH, MAX_TH)); + } +} + +static inline void rand_poly(polyline_t *p) +{ + long loc = myrand(0, black_len-1); + + p->pt[0].x = image_x(ref, ref->pixmap+black[loc]); + p->pt[0].y = image_y(ref, ref->pixmap+black[loc]); + p->pt[1].x = p->pt[0].x + myrand(0, 3); + p->pt[1].y = p->pt[0].y + myrand(0, 3); + p->len = 2; + p->th = myrand(MIN_TH, MAX_TH); +} + +static pcb_t *load_str(char *fn) +{ +#if 0 + char line[256]; + FILE *f = fopen(fn, "r"); + pcb_t *p; + if (f == NULL) + return 0; + p = calloc(sizeof(pcb_t), 1); + while(fgets(line, sizeof(line), f) != NULL) { + char *s = line; + int x1, y1, x2, y2, th; + if (strncmp(s, "stroke", 6) == 0) + s+=6; + + if (sscanf(s, "%d %d %d %d %d", &x1, &y1, &x2, &y2, &th) == 5) { + stroke_t *s = &p->str[p->len]; + s->x1 = x1; + s->y1 = y1; + s->x2 = x2; + s->y2 = y2; + s->th = th; + p->len++; + } + } + fclose(f); + return p; +#endif + return NULL; +} + +void *pcb_create(void) +{ + pcb_t *p = malloc(sizeof(pcb_t)); + int n; + + if (default_new != NULL) { + memcpy(p, default_new, sizeof(pcb_t)); + return p; + } + + for(n = 0; n < MAX_POLYS; n++) + rand_poly(&p->poly[n]); + + return p; +} + +static inline void pcb_mutate_append(polyline_t *p) +{ + if (p->len >= MAX_STROKES) + return; + + p->pt[p->len].x = p->pt[p->len-1].x + myrand(2, 10) - 5; + p->pt[p->len].y = p->pt[p->len-1].y + myrand(2, 10) - 5; + p->len++; +} + +static inline void pcb_mutate_insert(polyline_t *p) +{ + if (p->len >= MAX_STROKES) + return; + + memmove(p->pt+1, p->pt, p->len * sizeof(point_t)); + p->pt[0].x = p->pt[1].x + myrand(2, 10) - 5; + p->pt[0].y = p->pt[1].y + myrand(2, 10) - 5; + p->len++; +} + +static inline void pcb_mutate_del(polyline_t *p) +{ + int rem, idx; + + if (p->len < 3) + return; + + idx = myrand(0, p->len-1); + rem = p->len - idx - 1; + if (rem > 0) + memmove(p->pt+idx, p->pt+idx+1, rem*sizeof(point_t)); + p->len--; +} + +static inline void pcb_mutate_split(polyline_t *p) +{ + int idx, rem; + if (p->len >= MAX_STROKES) + return; + + idx = myrand(1, p->len-1); + rem = p->len - idx - 1; + if (rem > 0) + memmove(p->pt+idx+1, p->pt+idx, rem*sizeof(point_t)); + p->pt[idx].x = (p->pt[idx-1].x + p->pt[idx+1].x)/2 + myrand(2, 10) - 5; + p->pt[idx].y = (p->pt[idx-1].y + p->pt[idx+1].x)/2 + myrand(2, 10) - 5; + +} + +static inline void pcb_mutate_chg(polyline_t *p) +{ + int dirx = (rand() % 3) - 1; + int diry = (rand() % 3) - 1; + int idx = myrand(0, p->len-1); + + tune(p->pt[idx].x, 0, ref->sx, dirx); + tune(p->pt[idx].y, 0, ref->sy, diry); +} + +void pcb_mutate(void *data) +{ + pcb_t *p = data; + int n = myrand(0, 100); + int pi = myrand(0, MAX_POLYS-1); + + if (n > 65) + pcb_mutate_chg(&p->poly[pi]); + switch(n % 4) { + case 0: pcb_mutate_append(&p->poly[pi]); break; + case 1: pcb_mutate_insert(&p->poly[pi]); break; + case 2: pcb_mutate_del(&p->poly[pi]); + case 3: pcb_mutate_split(&p->poly[pi]); + } +} + +gp_pop_t pop = { + .len = 16, + .weak_kill = 5, + .clone_times = 2, + .create = pcb_create, + .score = pcb_score, + .mutate = pcb_mutate, + .clone = pcb_clone, + .dump = pcb_dump +}; + +int main(int argc, char *argv[]) +{ + int n; + + common_init(argc, argv); + + gp_setup(&pop); + + for(n = 0; n < 10000; n++) { + gp_iterate(&pop); + if ((pop.pop_cnt % 20) == 0) + gp_dump(stdout, &pop, 1); + } + pnm_save(ref, DUMPDIR "ref.pnm"); + free(black); +} Index: pcb_common.h =================================================================== --- pcb_common.h (revision 7398) +++ pcb_common.h (revision 7399) @@ -1,5 +1,7 @@ static inline void pcb_draw(image_t *img, pcb_t *p); static pcb_t *load_str(char *fn); +static inline int pcb_num_strokes(pcb_t *p); +static void pcb_dump_str(FILE *f, pcb_t *p); pcb_t *default_new = NULL; @@ -69,13 +71,12 @@ double pcb_score(void *data) { - pcb_t *p = data; double scr; pcb_clear(canvas); pcb_draw(canvas, data); scr = pcb_diff(canvas, ref); - return scr + (p->len+1) * stroke_penalty; + return scr + (pcb_num_strokes(data)+1) * stroke_penalty; } #define tune(dst, min, max, delta) \ @@ -88,16 +89,13 @@ const char *pcb_dump(void *data, int population_id, int individual_id) { - pcb_t *p = data; image_t *img = canvas; static char s[256]; FILE *f; - int n; snprintf(s, sizeof(s), DUMPDIR "stroke_%04d_%02d.str", population_id, individual_id); f = fopen(s, "w"); - for(n = 0; n < p->len; n++) - fprintf(f,"stroke %d %d %d %d %d\n", p->str[n].x1, p->str[n].y1, p->str[n].x2, p->str[n].y2, p->str[n].th); + pcb_dump_str(f, data); fclose(f); pcb_shadow(img, ref);