/************************************************************************** I D F . C ***************************************************************************/ /***************************************************************************** FILENAME : idf.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" #define PIECE_24_DINOSAUR YES #define OFFSET 30 extern int inverse_isthmus; extern WINDOW *funcwin; extern char string[70]; float distance(); /********************************************************************** M A T C H _ E M ***********************************************************************/ match_em (piece1, p1_indx, next_piece, p2_indx, offset, positive) int piece1, p1_indx, next_piece, p2_indx; int offset, positive; { int i1s, i1e, i2s, i2e; int p1_x1, p1_x2, p1_y1, p1_y2; int p2_x1, p2_x2, p2_y1, p2_y2; int start1, end1, start2, end2; /* undraw it */ drawpiece (piece1, UNDRAW); /*draw_skeleton(piece1, UNDRAW); */ /* end undraw it */ if (positive) { printit ("POSITIVE "); i1s = piece[piece1].dmtisth[p1_indx].indexbeg; i1e = piece[piece1].dmtisth[p1_indx].indexend; i2s = piece[next_piece].inv_isth[p2_indx].indexbeg; i2e = piece[next_piece].inv_isth[p2_indx].indexend; } else { printit ("NEGATIVE "); i1s = piece[piece1].inv_isth[p1_indx].indexbeg; i1e = piece[piece1].inv_isth[p1_indx].indexend; i2s = piece[next_piece].dmtisth[p2_indx].indexbeg; i2e = piece[next_piece].dmtisth[p2_indx].indexend; } i1s = i1s + offset; i1e = i1e + offset; movepiece(piece1, i1s, i1e, next_piece, i2s, i2e, 255); /*RWW */ start1 = i1s - OFFSET; end1 = i1e + OFFSET; start2 = i2s; end2 = i2e; get_pts (piece1, start1, end1, &p1_x1, &p1_y1, &p1_x2, &p1_y2); p2_x1 = p1_x1; p2_y1 = p1_y1; p2_x2 = p1_x2; p2_y2 = p1_y2; find_closest_pts (next_piece, &start2, &end2, &p2_x1, &p2_y1, &p2_x2, &p2_y2); /* VIS$DRAWLINE (p1_x1, p1_y1, p1_x2, p1_y2, 3); VIS$DRAWLINE (p2_x1, p2_y1, p2_x2, p2_y2, 3); */ movepiece(piece1, start1, end1, next_piece, start2, end2, 255); drawpiece (piece1, 255); /*draw_skeleton(piece1, 3); */ } /* end function */ /************************************************************************* M O V E P I E C E **************************************************************************/ movepiece (piece1, start1, end1, piece2, start2, end2, color) int piece1, start1, end1, piece2, start2, end2, color; { double radians; double p1_rads, p2_rads; float dx, dy; float d1, d2; float diff; int delx, dely; int midnegx,midnegy, midposx,midposy; int p1_x1, p1_x2, p1_y1, p1_y2; int p2_x1, p2_x2, p2_y1, p2_y2; get_pts (piece1, start1, end1, &p1_x1, &p1_y1, &p1_x2, &p1_y2); get_pts (piece2, start2, end2, &p2_x1, &p2_y1, &p2_x2, &p2_y2); dx = p2_x2 - p2_x1; dy = p2_y2 - p2_y1; radians = atan2 ( (double)dy, (double)dx); p2_rads = radians; dx = p1_x2 - p1_x1; dy = p1_y2 - p1_y1; radians = atan2 ( (double)dy, (double)dx); p1_rads = radians; diff = (float)(p2_rads - p1_rads); sprintf (string, "radians -> %2.2f theta -> %2.2f\n ", diff, (float)(diff * 57.3) ); printit(string); rotate_piece (piece1, diff); get_pts (piece1, start1, end1, &p1_x1, &p1_y1, &p1_x2, &p1_y2); get_pts (piece2, start2, end2, &p2_x1, &p2_y1, &p2_x2, &p2_y2); findmidpoint(p2_x1, p2_y1, p2_x2, p2_y2, &midnegx,&midnegy); findmidpoint(p1_x1, p1_y1, p1_x2, p1_y2, &midposx,&midposy); delx = (midnegx - midposx); dely = (midnegy - midposy); transpoly (piece1, (float)delx, (float)dely); get_pts (piece1, start1, end1, &p1_x1, &p1_y1, &p1_x2, &p1_y2); get_pts (piece2, start2, end2, &p2_x1, &p2_y1, &p2_x2, &p2_y2); d1 = distance (p1_x1, p1_y1, p2_x2, p2_y2); d2 = distance (p1_x1, p1_y1, p2_x1, p2_y1); /*printf ("d1 is %2.2f \n", d1); printf ("d2 is %2.2f \n", d2); */ if (d2 < d1) { rotate_piece (piece1, M_PI); get_pts (piece1, start1, end1, &p1_x1, &p1_y1, &p1_x2, &p1_y2); get_pts (piece2, start2, end2, &p2_x1, &p2_y1, &p2_x2, &p2_y2); findmidpoint(p2_x1, p2_y1, p2_x2, p2_y2, &midnegx,&midnegy); findmidpoint(p1_x1, p1_y1, p1_x2, p1_y2, &midposx,&midposy); delx = (midnegx - midposx); dely = (midnegy - midposy); transpoly (piece1, (float)delx, (float)dely); } #ifdef ROGER #endif } /**************************************************************************** R O T A T E _ P I E C E *****************************************************************************/ rotate_piece(pcnum,radians) int pcnum; float radians; { int i; float x; double cs,sn; /*radeg = (3.14 / 180.0) * theta; */ cs = cos((double)radians); sn = sin((double)radians); center(pcnum); /* **************************** */ /* rotate the border points */ /* **************************** */ for(i=1;i<=piece[pcnum].pathcnt;i++) { x = piece[pcnum].centx + (cs*(piece[pcnum].avgx[i] - piece[pcnum].centx)) - (sn*(piece[pcnum].avgy[i] - piece[pcnum].centy)); piece[pcnum].avgy[i] = piece[pcnum].centy + (sn*(piece[pcnum].avgx[i] - piece[pcnum].centx))+ (cs*(piece[pcnum].avgy[i] - piece[pcnum].centy)); piece[pcnum].avgx[i] = x; } /* **************************** */ /* rotate the skeleton points */ /* **************************** */ for(i=1;i<=piece[pcnum].pos_skelx[0];i++) { x = piece[pcnum].centx + (cs*(piece[pcnum].pos_skelx[i] - piece[pcnum].centx)) - (sn*(piece[pcnum].pos_skely[i] - piece[pcnum].centy)); piece[pcnum].pos_skely[i] = piece[pcnum].centy + (sn*(piece[pcnum].pos_skelx[i] - piece[pcnum].centx))+ (cs*(piece[pcnum].pos_skely[i] - piece[pcnum].centy)); piece[pcnum].pos_skelx[i] = x; } for(i=1;i<=piece[pcnum].inv_skelx[0];i++) { x = piece[pcnum].centx + (cs*(piece[pcnum].inv_skelx[i] - piece[pcnum].centx)) - (sn*(piece[pcnum].inv_skely[i] - piece[pcnum].centy)); piece[pcnum].inv_skely[i] = piece[pcnum].centy + (sn*(piece[pcnum].inv_skelx[i] - piece[pcnum].centx))+ (cs*(piece[pcnum].inv_skely[i] - piece[pcnum].centy)); piece[pcnum].inv_skelx[i] = x; } center(pcnum); } #ifdef ROGER movepiece(currpiece, indxj, indxk, absjx, absjy, abskx, absky, color) int currpiece, indxj, indxk, absjx, absjy, abskx, absky, color; /*draw_all_isthmii (pcnum, UNDRAW, UNDRAW, NO); */ #endif /***************************************************************************** GPH_ISTH_DIST *****************************************************************************/ gph_isth_dist (pcnum, graphit) int pcnum, graphit; { int y, i, x2, y2, ind; int numisth, index1, index2; int color = 5; if (!inverse_isthmus) { color = 6; numisth = piece[pcnum].isthnum; for (i=1; i<= numisth; i++) { #ifdef ROGER printf ("index1: %d\n", piece[pcnum].dmtisth[i].indexbeg); printf ("index2: %d\n", piece[pcnum].dmtisth[i].indexend); printf ("length: %d\n", piece[pcnum].dmtisth[i].lenseg); #endif index1 = piece[pcnum].dmtisth[i].indexbeg - BACKOFF; index2 = (piece[pcnum].dmtisth[i].indexend + BACKOFF); y = (int)piece[pcnum].avgy[index2 - BACKOFF]; if (index1 < 0) index1 = piece[pcnum].pathcnt + index1; ind = piece[pcnum].dmtisth[i].branch_index; x2 = (int)piece[pcnum].pos_skelx[ind]; y2 = (int)piece[pcnum].pos_skely[ind]; calc_dist (pcnum, index1, index2, i); printstat(piece[pcnum].dmtisth[i].lenseg, piece[pcnum].dmtisth[i].skeldist, piece[pcnum].dmtisth[i].index_dist); if (graphit) { gph_curv_dist (pcnum, 256 /*y*/, index1, index2, color); color = color + 1 ; if (numisth > 1) waitforkey(); } } } else { numisth = piece[pcnum].inv_isthnum; for (i=1; i<= numisth; i++) { #ifdef ROGER printf ("index1: %d\n", piece[pcnum].inv_isth[i].indexbeg); printf ("index2: %d\n", piece[pcnum].inv_isth[i].indexend); printf ("length: %d\n", piece[pcnum].inv_isth[i].lenseg); #endif index1 = piece[pcnum].inv_isth[i].indexbeg - BACKOFF; index2 = (piece[pcnum].inv_isth[i].indexend + BACKOFF); y = (int)piece[pcnum].avgy[index2 - BACKOFF]; ind = piece[pcnum].inv_isth[i].branch_index; x2 = (int)piece[pcnum].inv_skelx[ind]; y2 = (int)piece[pcnum].inv_skely[ind]; calc_dist (pcnum, index1, index2, i); printstat(piece[pcnum].inv_isth[i].lenseg, piece[pcnum].inv_isth[i].skeldist, piece[pcnum].inv_isth[i].index_dist); if (graphit) { gph_curv_dist (pcnum, 256 /*y*/, index1, index2, color); color = color + 1; if (numisth > 1) waitforkey(); } } } } /* end function */ /************************************************************************** GPH_CURV_DIST ***************************************************************************/ gph_curv_dist(piecenum,gphabs,start, end, color) int piecenum,gphabs, start, end, color; { int i,j,k,x; float ldist, ldist2; int y1,y2; int temp, p; ldist = 256.0 /*0.0*/; drawline((int)ldist, gphabs,511,gphabs,255); p = piece[piecenum].pathcnt; if (inverse_isthmus) { for(i=end; i>=start; i--) { if (i < 1) /* make it a periodic function */ { x = i + p; } else { x = i % p; /* mod it */ } if (x == 0) { y1 = gphabs-round(piece[piecenum].curv[p]); y2 = gphabs-round(piece[piecenum].curv[p-1]); ldist += piece[piecenum].l[p]; ldist2 = ldist + piece[piecenum].l[p-1]; } else if (x == 1) { y1 = gphabs-round(piece[piecenum].curv[1]); y2 = gphabs-round(piece[piecenum].curv[p]); ldist += piece[piecenum].l[1]; ldist2 = ldist + piece[piecenum].l[p]; } else { y1 = gphabs-round(piece[piecenum].curv[x]); y2 = gphabs-round(piece[piecenum].curv[x-1]); ldist += piece[piecenum].l[x]; ldist2 = ldist + piece[piecenum].l[x-1]; } if(y1<0) y1 = 0; if(y2<0) y2 = 0; if(y1>480) y1 = 512; if(y2>480) y2 = 512; drawline(round(ldist),y1,round(ldist2),y2,color); } } /* */ else { for(i=start; i<=end; i++) { if (i < 1) /* make it a periodic function */ { x = i + p; } else { x = i % p; /* mod it */ } if (x == 0 || x == p) { y1 = gphabs-round(piece[piecenum].curv[p]); y2 = gphabs-round(piece[piecenum].curv[1]); ldist += piece[piecenum].l[p]; ldist2 = ldist + piece[piecenum].l[1]; } else { y1 = gphabs-round(piece[piecenum].curv[x]); y2 = gphabs-round(piece[piecenum].curv[x+1]); ldist += piece[piecenum].l[x]; ldist2 = ldist + piece[piecenum].l[x+1]; } if(y1<0) y1 = 0; if(y2<0) y2 = 0; if(y1>480) y1 = 512; if(y2>480) y2 = 512; drawline(round(ldist),y1,round(ldist2),y2,color); #ifdef ROGER printf ("y1: %d actual \n", y1); printf ("y2: %d actual \n", y2); printf ("curv[%d]: %d\n", x+1, round(piece[piecenum].curv[x+1]) ); printf ("curv[%d]: %d\n", x, round(piece[piecenum].curv[x]) ); printf ("\n"); printf ("ghabs: %d y1: %d y2: %d\n", gphabs, y1, y2); #endif } } /* end else*/ } /* end function */ try_match() { int pcnum, next_piece, pos, neg; int offset; getdata( &pos); getdata( &next_piece); getdata( &neg); getdata( &offset); match_em (currpiece, pos, next_piece, neg, offset, NO); } getdata(data) int *data; { int g; echo(); wmove(funcwin,19,15); waddstr(funcwin,"Enter # => "); wrefresh(funcwin); wscanw(funcwin,"%d",&g); wrefresh(funcwin); wmove(funcwin,19,15); waddstr(funcwin," "); wrefresh(funcwin); *data = g; noecho(); } graph_one (pcnum, index, color) int pcnum, index, color; { int index1, index2, offset; if (!inverse_isthmus) { index1 = piece[pcnum].dmtisth[index].indexbeg - BACKOFF; index2 = (piece[pcnum].dmtisth[index].indexend + BACKOFF); sprintf (string, "Piece %d Positive Isthmus %d ", pcnum, index); #ifdef ROGER alph( string, 's', 330, 130 ); accenthoriz ( (int)piece[pcnum].avgx[index1], (int)piece[pcnum].avgy[index1], 255); accenthoriz ( (int)piece[pcnum].avgx[index2], (int)piece[pcnum].avgy[index2], 255); gph_curv_dist (pcnum, 256 , index1, index2, color); /*offset = piece[pcnum].dmtisth[index].correl_offset; waitforkey(); */ #endif getdata(&offset); gph_curv_dist (pcnum, 256 , index1 + offset, index2, color+18); } else { index1 = piece[pcnum].inv_isth[index].indexbeg - BACKOFF; index2 = (piece[pcnum].inv_isth[index].indexend + BACKOFF); sprintf (string, "Piece %d Inverse Isthmus %d ", pcnum, index); alph( string, 's', 330, 150 ); accenthoriz ( (int)piece[pcnum].avgx[index1], (int)piece[pcnum].avgy[index1], 255); accenthoriz ( (int)piece[pcnum].avgx[index2], (int)piece[pcnum].avgy[index2], 255); #ifdef ROGER #endif gph_curv_dist (pcnum, 256 , index1, index2, color); } } /* end function */ scale_all_pieces() { int i; float dx = 0.5, dy = 0.5; inverse_isthmus = 0; for (i=1; i<= piecenum;i++) { scalepoly (dx, dy, i); scale_skeleton (dx, dy, i); } printit("Done SCALING"); } /* end function */ calc_all_skel_dist() { int i; inverse_isthmus = 0; for (i=1; i<= piecenum;i++) { currpiece = i; gph_isth_dist (currpiece, 0); } inverse_isthmus = 1; for (i=1; i<= piecenum;i++) { currpiece = i; gph_isth_dist (currpiece, 0); } printit("Done calculating distances"); } match_controller() { int i; for (i=1; i<=piecenum; i++) /* draw all pieces */ { drawpiece (i, 255); /* draw_all_isthmii (i, 255, 255, NO); */ /*draw_skeleton(i, 255); */ } /* end draw it */ #ifdef PIECE_4_OF_24_DINOSAUR /* working4.dir pieces */ match_em (1, 1, 2, 2, 0, YES); match_em (4, 1, 1, 1, 1, YES); match_em (3, 2, 4, 1, -1, YES); match_em (2, 1, 3, 2, 0, YES); #endif #ifdef PIECE_24_DINOSAUR match_em (2, 1, 1, 2, 0, NO); match_em (8, 1, 1, 1, 0, YES); match_em (7, 3, 2, 2, 0, NO); match_em (3, 3, 2, 2, 0, YES); match_em (6, 3, 7, 2, 0, YES); match_em (4, 1, 3, 2, 0, NO); /*match_em (5, 1, 6, 2, 0, YES); */ match_em (5, 1, 19, 2, 0, YES); waitforkey(); match_em (11, 1, 6, 1, 0, YES); match_em (10, 3, 7, 1, 0, YES); match_em (9, 3, 8, 3, 0, NO); match_em (12, 1, 5, 2, 0, NO); match_em (15, 2, 11, 3, 0, NO); match_em (14, 2, 10, 1, 0, YES); match_em (13, 2, 9, 1, 0, YES); match_em (16, 1, 12, 3, 0, NO); match_em (18, 2, 15, 1, 0, YES); /*match_em (19, 2, 14, 3, 0, NO);*/ /*match_em (19, 2, 14, 3, 0, NO);*/ match_em (17, 1, 18, 2, 0, YES); match_em (20, 1, 19, 2, 0, NO); match_em (24, 2, 17, 1, 0, YES); match_em (23, 3, 18, 1, 0, YES); match_em (22, 1, 19, 1, 0, NO); match_em (21, 1, 20, 2, 0, NO); #endif #ifdef ROGER waitforkey(); redscrn(); for (i=1; i<=piecenum; i++) { drawpiece (i, 255); /*draw_skeleton(i, 255); */ } sprintf (string, "puzzle pieces assembled"); alph( string, 'b', 120, 20 ); #endif } /* end function */ draw_all_pieces (start, total_pieces, draw_isthmii) int start, total_pieces, draw_isthmii; { int pcnum; for (pcnum=start; pcnum<= total_pieces;pcnum++) { drawpiece (pcnum, DRAW); if (draw_isthmii) { /*draw_all_isthmii (pcnum, DRAW, DRAW, NO); */ /*draw_skeleton(pcnum, DRAW); */ } } } /* end function */ /********************************************************************** S C A L E S K E L E T O N ***********************************************************************/ scale_skeleton (scalex,scaley,pnm) float scalex,scaley; int pnm; { int i; for(i=1; i<= piece[pnm].pathcnt; i++) { piece[pnm].pos_skelx[i] = (int)(piece[pnm].pos_skelx[i] * scalex); piece[pnm].pos_skely[i] = (int)(piece[pnm].pos_skely[i] * scaley); piece[pnm].inv_skelx[i] = (int)(piece[pnm].inv_skelx[i] * scalex); piece[pnm].inv_skely[i] = (int)(piece[pnm].inv_skely[i] * scaley); } } /********************************************************************** G E T - P T S ***********************************************************************/ get_pts (pcnum, start, end, p1_x1, p1_y1, p1_x2, p1_y2) int pcnum, start, end, *p1_x1, *p1_y1, *p1_x2, *p1_y2; { *p1_x1 = (int)(piece[pcnum].avgx[start]); *p1_y1 = (int)(piece[pcnum].avgy[start]); *p1_x2 = (int)(piece[pcnum].avgx[end]); *p1_y2 = (int)(piece[pcnum].avgy[end]); } /* end function */ /********************************************************************** FIND - P T S ***********************************************************************/ find_closest_pts (pcnum, start, end, p1_x1, p1_y1, p1_x2, p1_y2) int pcnum, *start, *end, *p1_x1, *p1_y1, *p1_x2, *p1_y2; { float dist_so_far = 50000.0, dis; int x, keep_sub = 0; int x1,y1; for (x = *end; x<= *end + (OFFSET + 20); x++) { x1 = (int)(piece[pcnum].avgx[x]); y1 = (int)(piece[pcnum].avgy[x]); dis = distance (x1,y1, *p1_x1, *p1_y1); if (dis < dist_so_far) { dist_so_far = dis; keep_sub = x; } } *p1_x1 = (int)(piece[pcnum].avgx[keep_sub]); *p1_y1 = (int)(piece[pcnum].avgy[keep_sub]); *end = keep_sub; dist_so_far = 50000.0; for (x = *start; x >= *start - (OFFSET + 20); x--) { x1 = (int)(piece[pcnum].avgx[x]); y1 = (int)(piece[pcnum].avgy[x]); dis = distance (x1,y1, *p1_x2, *p1_y2); if (dis < dist_so_far) { dist_so_far = dis; keep_sub = x; } } *p1_x2 = (int)(piece[pcnum].avgx[keep_sub]); *p1_y2 = (int)(piece[pcnum].avgy[keep_sub]); *start = keep_sub; } /* end function */ /********************************************************************** E N D M O D U L E ***********************************************************************/