/* Store in the rightface field of each edge the number of the face on the right hand side of that edge. Faces are numbered 0,1,.... Also store in facestart[i] an example of an edge in the clockwise orientation of the face boundary, and the size of the face in facesize[i], for each i. Returns the number of faces. */ void makeDual() { register int i, sz; register EDGE *e, *ex, *ef, *efx; RESETMARKS; nf = 0; for (i = 0; i < nv; ++i) { e = ex = firstedge[i]; do { if (!ISMARKEDLO(e)) { facestart[nf] = ef = efx = e; faceSets[nf] = EMPTY_SET; sz = 0; do { ef->rightface = nf; ADD(faceSets[nf], ef->end); MARKLO(ef); ef = ef->inverse->prev; ++sz; } while (ef != efx); faceSize[nf] = sz; ++nf; } e = e->next; } while (e != ex); } }
/* Store in the rightface field of each edge the number of the face on the right hand side of that edge. Faces are numbered 0,1,.... Also store in facestart[i] an example of an edge in the clockwise orientation of the face boundary, and the size of the face in facesize[i], for each i. Returns the number of faces. */ void makeDual(PLANE_GRAPH *pg) { register int i, sz; register PG_EDGE *e, *ex, *ef, *efx; RESETMARKS(pg); //first allocate the memory to store faces if this has not yet been done int maxf = 2*pg->maxn - 4; if(pg->maxf < maxf){ if(pg->facestart!=NULL){ free(pg->facestart); } if(pg->faceSize!=NULL){ free(pg->faceSize); } pg->maxf = maxf; pg->facestart = (PG_EDGE **)malloc(sizeof(PG_EDGE *)*maxf); if(pg->facestart == NULL){ pg->maxf = 0; return; } pg->faceSize = (int *)malloc(sizeof(int)*maxf); if(pg->faceSize == NULL){ pg->maxf = 0; free(pg->facestart); return; } } int nf = 0; for (i = 0; i < pg->nv; ++i) { e = ex = pg->firstedge[i]; do { if (!ISMARKEDLO(e)) { pg->facestart[nf] = ef = efx = e; sz = 0; do { ef->rightface = nf; MARKLO(ef); ef = ef->inverse->prev; ++sz; } while (ef != efx); pg->faceSize[nf] = sz; ++nf; } e = e->next; } while (e != ex); } pg->nf = nf; pg->dualComputed = TRUE; }
void walk_faces(int i, int face_colour) { int r, c, s; int v1, v2, v3; int a1, a2, a3; vertices_of_face(i, &v1, &v2, &v3); // If we have already visited this face then there // is nothing to do here so leave. if (ISMARKED(facestart[i])) return; // Otherwise we tag this face and recurse on the // three neighbours. MARKLO(facestart[i]); // printf("marking face %d\n", i); // If all three vertices of this face are uncoloured // then we are entering walk_faces for for the first time // so we arbitrarily 3-colour the vertices of this face. if (vertex_colour[v1] < 0 && vertex_colour[v2] < 0 && vertex_colour[v3] < 0) { vertex_colour[v1] = 0; vertex_colour[v2] = 1; vertex_colour[v3] = 2; } else if (vertex_colour[v1] >= 0 && vertex_colour[v2] >= 0 && vertex_colour[v3] >= 0) { // Terminating case, do nothing. } else { // Two vertices must be coloured so we can colour the third. if (vertex_colour[v1] >= 0 && vertex_colour[v2] >= 0) { assert(vertex_colour[v3] < 0); vertex_colour[v3] = other_colour(vertex_colour[v1], vertex_colour[v2]); } else if (vertex_colour[v1] >= 0 && vertex_colour[v3] >= 0) { assert(vertex_colour[v2] < 0); vertex_colour[v2] = other_colour(vertex_colour[v1], vertex_colour[v3]); } else if (vertex_colour[v2] >= 0 && vertex_colour[v3] >= 0) { assert(vertex_colour[v1] < 0); vertex_colour[v1] = other_colour(vertex_colour[v2], vertex_colour[v3]); } else { printf("%d, %d, %d\n", vertex_colour[v1], vertex_colour[v2], vertex_colour[v3]); assert(FALSE); } } ordered_triple(v1, v2, v3, &r, &c, &s); // Have we seen the row label r before? If not, make a note of how // we will really present it. if (row_label[r] < 0) { row_label[r] = max_row_label; max_row_label++; } if (col_label[c] < 0) { col_label[c] = max_col_label; max_col_label++; } if (sym_label[s] < 0) { sym_label[s] = max_sym_label; max_sym_label++; } triple e; e.x = row_label[r]; e.y = col_label[c]; e.z = sym_label[s]; if (face_colour == 0) { T1[max_entry_index1] = e; max_entry_index1++; } else { // face_colour == 1 T2[max_entry_index2] = e; max_entry_index2++; } // tags of the three adjacent faces a1 = facestart[i]->invers->tag; a2 = facestart[i]->invers->prev->invers->tag; a3 = facestart[i]->invers->prev->invers->prev->invers->tag; if (face_colour == 0) face_colour = 1; else face_colour = 0; walk_faces(a1, face_colour); walk_faces(a2, face_colour); walk_faces(a3, face_colour); }