// A multi_pword is a structure which keeps track of week tiles containing // muliple triangles. As such it keeps track of one word, but unfolding data // for multiple triangles typedef struct { word w; // The word Pletter lexi; // For the LexiTest int count[3]; // How is the word balanced? int mod2; // 1 if even # of letters, -1 if odd number int lexi_count; // Also for the LexiTest int num; // Number of triangles we keep track of matrix *m; // The transformation which takes the first edge of // our unfolding to the last phull *h; // Unfolding data } multi_pword; typedef struct { multi_pword *w; int MAX_DEPTH; // stores the length of w int l; // stores the number of elements actually stored in w } multi_pword_list; //-------------------------------------------- // Functions for manipulating multi_pword //int pword_free=0, pword_alloc=0; // this initializes a pword // the phulls must be initialized seperately void multi_pword_empty(w, n) multi_pword *w; int n; { int i; w->count[0]=w->count[1]=w->count[2]=0; w->w.first=w->w.last=w->lexi=NULL; w->lexi_count=0; w->w.l=0; w->mod2=1; w->num=n; w->m=(matrix *) malloc(w->num*sizeof(matrix)); for (i=0; inum; i++){ w->m[i].m[0][0]=1; w->m[i].m[0][1]=0; w->m[i].m[0][2]=0; w->m[i].m[1][0]=0; w->m[i].m[1][1]=1; w->m[i].m[1][2]=0; } w->h=(phull *) malloc(w->num*sizeof(phull)); } // i is the letter to add void multi_pword_addLetter(w,i) multi_pword *w; int i; { if (w->w.last!=NULL){ // theres is at least one letter w->w.last->next=(Pletter) malloc (sizeof(struct pletter)); //pword_alloc++; w->w.last->next->l=i; w->w.last->next->next=NULL; w->w.last->next->prev=w->w.last; w->w.last=w->w.last->next; } else { // the first letter w->w.last=(Pletter) malloc (sizeof(struct pletter)); //pword_alloc++; w->w.last->l=i; w->w.first=w->w.last; w->w.last->next=NULL; w->lexi=NULL; w->w.last->prev=NULL; } w->count[i]+=w->mod2; w->mod2*=-1; w->w.l++; } // There has to be a better way to do this then a set of nested if statements, // BUT... // this adds a letter and records the reflections effect on on m, // at least two letters should already be present. // i is the current side being reflected in // r and T should be arrays of length w->num void multi_pword_addLetter_r(w,i,r,T) multi_pword *w; int i; reflection r[]; ptriangle T[]; { int j; if (w->mod2==1) // even number of letters- the usual orientation if (w->w.last->l==0) // last reflected was the first side if (i==2) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z1), 1); else // (i==1); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z1), -1); else if (w->w.last->l==1) // last reflected was the second side if (i==0) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z2), 1); else // (i==2); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z2), -1); else // w->w.last->l==2 last reflected third side if (i==1) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z3), 1); else // (i==0); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z3), -1); else // (w->mod2==-1) // odd number of letters- the opposite orientation if (w->w.last->l==0) // last reflected was the first side if (i==2) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z1), -1); else // (i==1); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z1), 1); else if (w->w.last->l==1) // last reflected was the second side if (i==0) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z2), -1); else // (i==2); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z2), 1); else // w->w.last->l==2 last reflected third side if (i==1) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z3), -1); else // (i==0); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z3), 1); for (j=0; jnum; j++) timesEquals(&(w->m[j]), &(r[j].m[i])); multi_pword_addLetter(w,i); } // same as above but accepts a triangle instead of a ptriangle void multi_pword_addLetter_rt(w,i,r,T) multi_pword *w; int i; reflection r[]; triangle T[]; { int j; if (w->mod2==1) // even number of letters- the usual orientation if (w->w.last->l==0) // last reflected was the first side if (i==2) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[0]), 1); else // (i==1); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[0]), -1); else if (w->w.last->l==1) // last reflected was the second side if (i==0) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[1]), 1); else // (i==2); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[1]), -1); else // w->w.last->l==2 last reflected third side if (i==1) // add the point to the right side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[2]), 1); else // (i==0); -- left side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[2]), -1); else // (w->mod2==-1) // odd number of letters- the opposite orientation if (w->w.last->l==0) // last reflected was the first side if (i==2) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[0]), -1); else // (i==1); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[0]), 1); else if (w->w.last->l==1) // last reflected was the second side if (i==0) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[1]), -1); else // (i==2); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[1]), 1); else // w->w.last->l==2 last reflected third side if (i==1) // add the point to the left side; for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[2]), -1); else // (i==0); -- right side for (j=0; jnum; j++) phull_insert(&(w->h[j]), eucTimes(&(w->m[j]),T[j].z[2]), 1); for (j=0; jnum; j++) timesEquals(&(w->m[j]), &(r[j].m[i])); multi_pword_addLetter(w,i); } // this adds the letter and performs the requested change // after a future_plexi_test void multi_pword_addLetter_lexi(w,i,lex) multi_pword *w; int i; int lex; { multi_pword_addLetter(w,i); if (lex==1){ w->lexi=w->lexi->next; w->lexi_count++; } else { //otherwise assume lex=0; w->lexi_count=0; w->lexi=w->w.first; } } void multi_pword_copy(w,new) multi_pword *w, *new; { int i; Pletter lw; multi_pword_empty(new, w->num); new->lexi_count=w->lexi_count; for (i=0; inum; i++){ new->m[i].m[0][0]=w->m[i].m[0][0]; new->m[i].m[0][1]=w->m[i].m[0][1]; new->m[i].m[0][2]=w->m[i].m[0][2]; new->m[i].m[1][0]=w->m[i].m[1][0]; new->m[i].m[1][1]=w->m[i].m[1][1]; new->m[i].m[1][2]=w->m[i].m[1][2]; } new->lexi=NULL; i=0; lw=w->w.first; while (lw!=NULL){ multi_pword_addLetter(new,lw->l); if (lw==w->lexi) new->lexi=new->w.last; lw=lw->next; } if (lw==w->lexi) new->lexi=new->w.last; //if (new->lexi==NULL){ // pword_print_file(stdout,w); // fprintf(stdout,"we have an error"); // fflush(stdout); //} for (i=0; inum; i++) phull_copy(&(w->h[i]),&(new->h[i])); } // this frees the memory used by a multi_pword void multi_pword_destroy(p) multi_pword *p; { int i; for (i=0; inum; i++) phull_destroy(&(p->h[i])); word_destroy(&(p->w)); free(p->h); free(p->m); } //--------------------------------------------- // multi_pword_list Functions void multi_pword_list_initialize(wl, MAX_DEPTH) multi_pword_list *wl; int MAX_DEPTH; { wl->w=(multi_pword *)malloc(MAX_DEPTH * sizeof(multi_pword)); wl->MAX_DEPTH=MAX_DEPTH; wl->l=0; } void multi_pword_list_destroy(wl) multi_pword_list *wl; { int i; for (i=0; i< wl->l; i++) multi_pword_destroy(&(wl->w[i])); free(wl->w); }