/************************************************************************** M A T C H . C ***************************************************************************/ /***************************************************************************** FILENAME : match.c PURPOSE : this sets up for the matching functions *****************************************************************************/ #include #include #include #include #include "statline.h" #include "piece.h" #include "isthdefs.h" #include "/usr/users/header/arrkey.h" #include extern struct timeval f; extern int oldsec; extern int file_create; extern int inverse_isthmus; extern int localx[2500], localy[2500]; extern char strg[79]; extern int debug; extern WINDOW *funcwin; extern float correl_control(); extern float euclid_dist(); int datafp; struct matches { int piece_num, pos_num, neg_pcnum, neg_num, gap, delete, area, path_length, pos_gap, neg_gap; float ave_sum; float ratio; float top_correl; int correl_index, offset; }; struct matches mtable[MAXSUB]; struct matches ptable[MAXSUB]; int msub=1; int oldmsub=1; float correlation[100]; /************************************************************************ BEST_FITTER *************************************************************************/ best_fitter(total_pcnum) int total_pcnum; { int pcnum, next_piece, numisth, inv_numisth; int pos, neg, ci; int pos_len, pos_skel_dist, pos_index; int neg_len, neg_skel_dist, neg_index; int n, area; int gs,ge,fs,fe; int small, offset; msub = 1; datafp = creat ("datafile", 0777); calc_all_skel_dist(); for (pcnum=1; pcnum <= total_pcnum; pcnum++) { ptable[msub].piece_num = pcnum; numisth = piece[pcnum].isthnum; if (numisth > 0) for (pos= 1; pos <= numisth; pos++) { ptable[msub].pos_num = pos; pos_len = piece[pcnum].dmtisth[pos].lenseg; pos_skel_dist = piece[pcnum].dmtisth[pos].skeldist; pos_index = piece[pcnum].dmtisth[pos].index_dist; for (next_piece= 1; next_piece <= total_pcnum; next_piece++) { if (next_piece != pcnum) { ptable[msub].neg_pcnum = next_piece; inv_numisth = piece[next_piece].inv_isthnum; for (neg= 1; neg <= inv_numisth; neg++) { neg_len = piece[next_piece].inv_isth[neg].lenseg; neg_skel_dist = piece[next_piece].inv_isth[neg].skeldist; neg_index = piece[next_piece].inv_isth[neg].index_dist; ptable[msub].neg_num = neg; if ( pos_index > neg_index+1 ) /* wont fit anyway */ { ptable[msub].delete = 1; } else { fs = piece[pcnum].dmtisth[pos].indexbeg - BACKOFF; fe = piece[pcnum].dmtisth[pos].indexend + BACKOFF; gs = piece[next_piece].inv_isth[neg].indexbeg - BACKOFF; ge = piece[next_piece].inv_isth[neg].indexend + BACKOFF; if ( (ge-gs) < (fe-fs) ) n = ge - gs; else n = fe -fs; ptable[msub].gap = sum_of_y (pcnum, next_piece, fs, ge, n, NO); if (ptable[msub].gap < MAXGAP) { ptable[msub].delete = 0; ptable[msub].top_correl = correl_control(piece[pcnum].curv, /* f(x) */ piece[next_piece].curv, /* g(x) */ gs, ge, fs, fe, &ci); if (ptable[msub].top_correl < MIN_CORREL) ptable[msub].delete = 1; else { ptable[msub].correl_index = ci; piece[pcnum].dmtisth[pos].correl_offset = ci; ptable[msub].area = sum_of_y(pcnum, next_piece, fs+ci, ge, n, NO); ptable[msub].ave_sum = (float)(ptable[msub].area) / (float)n; if (ptable[msub].ave_sum > MAXPL) ptable[msub].delete = 1; else { ptable[msub].gap = smallest_gap (pcnum, next_piece, fs, ge, n, &offset); ptable[msub].ave_sum = (float)(ptable[msub].gap)/(float)n; ptable[msub].path_length = n; if (ptable[msub].ave_sum > MAXPL-1) ptable[msub].delete = 1; else { ptable[msub].ratio = (float)(ptable[msub].pos_gap) / (float)(ptable[msub].gap); ptable[msub].ratio = ptable[msub].ratio * 100.0; if (ptable[msub].ratio > MAX_RATIO) ptable[msub].delete = 1; ptable[msub].offset = offset; piece[pcnum].dmtisth[pos].small_offset = offset; } /* end else ave_sum MAXPL -1 */ } /* end else ave_sum */ } /* end else top_correl < MIN_CORREL */ } else { ptable[msub].delete = 1; } } /* end-else */ msub++; if (msub > MAXSUB) printf ("MSUB -> %d too big for table-> %d\n", msub, MAXSUB); ptable[msub] = ptable[msub-1]; } /* end for neg*/ } /* endif != */ } /* end for nextpiece*/ } /* end for pos*/ } /* end for pcnum*/ printit ("DONE ALL PIECES"); copy_to_mtable (&msub); sort_table(msub); do_secondary_sort(msub); /*sprintf(strg," Sorted by Negative Isthmus"); dump_table (msub, total_pcnum, NO, strg); waitforkey(); */ sort_pl(msub); sprintf(strg," Sorted by AVE-GAP"); /*dump_table (msub, total_pcnum, NO, strg); */ after_sort (msub); waitforkey(); close(datafp); } /* end function */ dump_table(msub, total_pcnum, create_dfile, strg) int msub, total_pcnum, create_dfile; char strg[79]; { int i,x, prev =512; int prev_neg_num = 512; for (x=1; x<20; x++) printf ("\n"); printf (" ======================================================\n"); printf (" ------------ RAW CORRELATION DATA ----------------- \n"); printf (" ======================================================\n"); printf ("\n"); printf (" %s\n ", strg); printf ("\n"); printf (" Number of Pieces = %d\n", total_pcnum); printf ("\n"); printf (" Number of possible matchings: %d\n", oldmsub); printf (" Matches eliminated with preprocessing features: %d\n", oldmsub - msub); printf (" Number of viable candidate matchings: %d\n", msub); printf ("\n"); for (i=1; i<=msub; i++) { if (!mtable[i].delete) { if (prev != mtable[i].neg_pcnum || prev_neg_num != mtable[i].neg_num) printf ("\n"); print_stuff(i, create_dfile); prev = mtable[i].neg_pcnum; prev_neg_num = mtable[i].neg_num; } } } /* end function dump_table */ sort_pl(msub) int msub; { int i, n, done = 0; struct matches temp; n = msub; do { done = 1; for (i=1; i<= n - 1; i++) if (mtable[i+1].ave_sum < mtable[i].ave_sum) { temp = mtable[i]; mtable[i] = mtable[i+1]; mtable[i+1] = temp; done = 0; } } while (!done); } sort_table(msub) int msub; { int i, n, done = 0; struct matches temp; n = msub; do { done = 1; for (i=1; i<= n - 1; i++) if (mtable[i+1].neg_pcnum > mtable[i].neg_pcnum) { temp = mtable[i]; mtable[i] = mtable[i+1]; mtable[i+1] = temp; done = 0; } } while (!done); } mini_sort(start, end) int start, end; { int i, n, done = 0; struct matches temp; n = end; do { done = 1; for (i=start; i <= n-1; i++) if (mtable[i+1].neg_num > mtable[i].neg_num) { temp = mtable[i]; mtable[i] = mtable[i+1]; mtable[i+1] = temp; done = 0; } } while (!done); } do_secondary_sort(msub) int msub; { int start=1, end=2, prev; struct matches temp; prev = mtable[1].neg_pcnum; do { if (prev != mtable[end].neg_pcnum) { if (end - start > 1) mini_sort(start, end-1); prev = mtable[end].neg_pcnum; start = end; } end++; } while (end < msub); } /************************************************************************** CALC_DIST ***************************************************************************/ calc_dist (pcnum, index1, index2, num) int pcnum, index1, index2, num; { int x1, y1, p, x; int i, off; int mx1, mx2, my1, my2, midx2, midy2; p = piece[pcnum].pathcnt; mx1 = (int)piece[pcnum].avgx[index1]; my1 = (int)piece[pcnum].avgy[index1]; mx2 = (int)piece[pcnum].avgx[index2]; my2 = (int)piece[pcnum].avgy[index2]; findmidpoint (mx1, my1, mx2, my2, &midx2, &midy2); off = (M + 1); for (i=index1 - off; i<=index2 + off; i++) { #ifdef ROGER printf ("p: %d\n", p); printf ("CALCDIST: index1: %d index2: %d\n", index1, index2); printf ("x: %d y: %d\n", (int)piece[pcnum].avgx[i], (int)piece[pcnum].avgy[i]); if (i > p) /* make it a periodic function */ printf ("WOW i > p piece #: %d ind1: %d ind2: %d\n", pcnum, index1, index2); if (i < 1) /* make it a periodic function */ { x = i + p; printf ("WOW i < p NEGATIVE piece num: %d ind1: %d ind2: %d\n", pcnum, index1, index2); } else { x = i % p; /* mod it */ } #endif x = i; x1 = (int)piece[pcnum].avgx[x]; y1 = (int)piece[pcnum].avgy[x]; piece[pcnum].curv[x] = euclid_dist(x1,y1, midx2, midy2); piece[pcnum].l[x] = 1.0; } } /* end function */ /************************************************************************** SUM_OF_Y ***************************************************************************/ sum_of_y (pcnum, next_piece, fs, ge, n, do_pos_gap) int pcnum, next_piece, fs, ge, n, do_pos_gap; { int x, i, y1, y2, z; int sum = 0; int ldist = 256; if (do_pos_gap) { ptable[msub].pos_gap = 0; ptable[msub].neg_gap = 0; } for (i=fs; i <= fs+n; i++) { x = ( abs( (int)piece[pcnum].curv[i] - (int)piece[next_piece].curv[ge]) ); sum = sum + x; if (do_pos_gap) { z = (int)piece[pcnum].curv[i] - (int)piece[next_piece].curv[ge]; if (z > 0) ptable[msub].pos_gap = ptable[msub].pos_gap + x; else ptable[msub].neg_gap = ptable[msub].neg_gap + x; } ge--; } return (sum); } /* end function */ after_sort(msub) int msub; { int i,j, count=0; printf ("\n"); printf ("\n"); printf (" ======================================================\n"); printf (" ------------- FINAL PUZZLE PIECE MATINGS ------------ \n"); printf (" ======================================================\n"); printf ("\n"); printf ("\n"); for (i=1; i<=msub; i++) { if (!mtable[i].delete) { for (j= i; j <= msub; j++) { if ( ( mtable[i].piece_num == mtable[j].piece_num && mtable[i].neg_pcnum == mtable[j].neg_pcnum) || ( mtable[i].piece_num == mtable[j].neg_pcnum && mtable[i].neg_pcnum == mtable[j].piece_num) || ( mtable[i].piece_num == mtable[j].piece_num && mtable[i].pos_num == mtable[j].pos_num) || ( mtable[i].neg_pcnum == mtable[j].neg_pcnum && mtable[i].neg_num == mtable[j].neg_num) ) { mtable[j].delete = 1; } } /* endfor j */ print_stuff(i, file_create); count++; } /* endif !delete */ } /* endfor j */ printf ("\n"); printf ("\n"); printf (" Number of actual puzzle matches = %d\n", count); } /* end function after sort*/ print_stuff(i, file_create) int i, file_create; { printf ("%2d P#", mtable[i].piece_num); printf (" %2d", mtable[i].pos_num); printf ("->%2d", mtable[i].neg_pcnum); printf (" N#%2d", mtable[i].neg_num); printf (" Corr: %1.2f", mtable[i].top_correl); /* was %1.4f */ printf (" Off %2d", mtable[i].offset); printf (" AVE %3.2f", mtable[i].ave_sum); printf (" GAP %4d", mtable[i].gap); printf (" PL %3d", mtable[i].path_length); printf (" P %3d", mtable[i].pos_gap); printf (" N %4d", mtable[i].neg_gap); printf (" R %3.1f", mtable[i].ratio); printf ("\n"); if (file_create) write_to_data (i); /* printf (" Off%2d", mtable[i].correl_index); printf (" GAP %4d", mtable[i].area); */ } /* end function */ write_to_data(i) int i; { int r; char a[81]; char buffer[85]; sprintf (buffer, ""); sprintf (a, "%2d P#", mtable[i].piece_num); strcat (buffer, a); sprintf (a, " %2d", mtable[i].pos_num); strcat (buffer, a); sprintf (a, "->%2d", mtable[i].neg_pcnum); strcat (buffer, a); sprintf (a, " N#%2d", mtable[i].neg_num); strcat (buffer, a); sprintf (a, " Corr: %1.2f", mtable[i].top_correl); /* was %1.4f */ strcat (buffer, a); sprintf (a, " Off %2d", mtable[i].offset); strcat (buffer, a); sprintf (a, " AVE %3.2f", mtable[i].ave_sum); strcat (buffer, a); sprintf (a, " GAP %4d", mtable[i].gap); strcat (buffer, a); sprintf (a, " PL %3d", mtable[i].path_length); strcat (buffer, a); sprintf (a, " P %3d", mtable[i].pos_gap); strcat (buffer, a); sprintf (a, " N %4d", mtable[i].neg_gap); strcat (buffer, a); sprintf (a, " R %3.1f\n", mtable[i].ratio); strcat (buffer, a); strcat (buffer, '\0'); printf ("heres the buffer\n %s", buffer); r = write (datafp, buffer, 81 /*strlen(buffer)*/ ); /*printf ("strlen -> %d RESULT -> %d\n", strlen(buffer), r); */ } /* end function */ smallest_gap (pcnum, next_piece, fs, ge, n, offset) int pcnum, next_piece, fs, ge, n, *offset; { int m, smallest=32000; int num; for (m = -M; m <= M; m++) { num = sum_of_y (pcnum, next_piece, fs+m, ge, n, NO); if (num < smallest) { smallest = num; *offset = m; } } num = sum_of_y (pcnum, next_piece, fs+ (*offset), ge, n, YES); return (smallest); } /* deletes the rubbish */ copy_to_mtable (msub) int *msub; { int x; int sub = 1; for (x=1;x<=*msub;x++) if (!ptable[x].delete) { mtable[sub] = ptable[x]; sub++; } oldmsub = *msub; sub--; *msub = sub; } #ifdef ROGER if (debug) { printf ("=================================================\n"); printf ("this WONT FIT ANYWAY -->\n"); printf ("p: %d pos#: %d len: %d skel_dist: %d indexdist: %d\n", pcnum, pos, pos_len, pos_skel_dist, pos_index); printf ("o: %d neg#: %d len: %d skel_dist: %d indexdist: %d\n", next_piece, neg, neg_len, neg_skel_dist, neg_index); printf ("=================================================\n"); } if (pcnum == 7 && next_piece == 8) printf ("pcnum: %d pos#: %d next_piece: %d neg: %d\n", pcnum, pos, next_piece, neg); #endif #ifdef ROGER printf ("=========================================\n"); printf ("correl offset: %d -> top_val: %f\n", ci, ptable[msub].top_correl); printf ("gap offset: %d -> smallest gap: %d\n", offset, ptable[msub].gap); printf ("gap at best correl: %d\n", ptable[msub].area); printf ("=========================================\n"); #endif