Subdivision::Subdivision(const Point2d& a, const Point2d& b, const Point2d& c) // Initialize a subdivision to the triangle defined by the points a, b, c. { Point2d *da, *db, *dc; da = new Point2d(a), db = new Point2d(b), dc = new Point2d(c); Edge* ea = MakeEdge(); ea->EndPoints(da, db); Edge* eb = MakeEdge(); Splice(ea->Sym(), eb); eb->EndPoints(db, dc); Edge* ec = MakeEdge(); Splice(eb->Sym(), ec); ec->EndPoints(dc, da); Splice(ec->Sym(), ea); startingEdge = ea; }
/* glu_fastuidraw_gl_meshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ GLUhalfEdge *glu_fastuidraw_gl_meshMakeEdge( GLUmesh *mesh ) { GLUvertex *newVertex1= allocVertex(); GLUvertex *newVertex2= allocVertex(); GLUface *newFace= allocFace(); GLUhalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == nullptr || newVertex2 == nullptr || newFace == nullptr) { if (newVertex1 != nullptr) memFree(newVertex1); if (newVertex2 != nullptr) memFree(newVertex2); if (newFace != nullptr) memFree(newFace); return nullptr; } e = MakeEdge( &mesh->eHead ); if (e == nullptr) { memFree(newVertex1); memFree(newVertex2); memFree(newFace); return nullptr; } MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. * eOrg and eNew will have the same left face. */ GLUhalfEdge* __gl_meshAddEdgeVertex(GLUhalfEdge* eOrg) { GLUhalfEdge* eNewSym; GLUhalfEdge* eNew=MakeEdge(eOrg); if (eNew==NULL) { return NULL; } eNewSym=eNew->Sym; /* Connect the new edge appropriately */ Splice(eNew, eOrg->Lnext); /* Set the vertex and face information */ eNew->Org=eOrg->Dst; { GLUvertex* newVertex=allocVertex(); if (newVertex==NULL) { return NULL; } MakeVertex(newVertex, eNewSym, eNew->Org); } eNew->Lface=eNewSym->Lface=eOrg->Lface; return eNew; }
Edge* Connect(Edge* a, Edge* b) // Add a new edge e connecting the destination of a to the // origin of b, in such a way that all three have the same // left face after the connection is complete. // Additionally, the data pointers of the new edge are set. { Edge* e = MakeEdge(); Splice(e, a->Lnext()); Splice(e->Sym(), b); e->EndPoints(a->Dest(), b->Org()); return e; }
void InsertEdge(LGraph graph, Edge e) { /* for directed or undirected gragh to insert a new edge */ nodeptr newnode = (nodeptr)malloc(sizeof(struct node)); if (!newnode) { fprintf(stderr, "Memory is full, insert edge failed.\n"); exit(EXIT_FAILURE); } newnode->adjv = e->vc; newnode->next = NULL; newnode->wt = e->wt; MakeEdge(graph->G[e->vr], newnode); // if graph is undirected: nodeptr mirror = (nodeptr)malloc(sizeof(struct node)); mirror->adjv = e->vr; mirror->next = NULL; mirror->wt = e->wt; MakeEdge(graph->G[e->vc], mirror); graph->edge_num++; }
/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst * to eDst->Org, and returns the corresponding half-edge eNew. * If eOrg->Lface == eDst->Lface, this splits one loop into two, * and the newly created loop is eNew->Lface. Otherwise, two disjoint * loops are merged into one, and the loop eDst->Lface is destroyed. * * If (eOrg == eDst), the new face will have only two edges. * If (eOrg->Lnext == eDst), the old face is reduced to a single edge. * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges. */ GLUhalfEdge* __gl_meshConnect(GLUhalfEdge* eOrg, GLUhalfEdge* eDst) { GLUhalfEdge* eNewSym; int joiningLoops=FALSE; GLUhalfEdge* eNew=MakeEdge(eOrg); if (eNew==NULL) { return NULL; } eNewSym=eNew->Sym; if (eDst->Lface!=eOrg->Lface) { /* We are connecting two disjoint loops -- destroy eDst->Lface */ joiningLoops=TRUE; KillFace(eDst->Lface, eOrg->Lface); } /* Connect the new edge appropriately */ Splice(eNew, eOrg->Lnext); Splice(eNewSym, eDst); /* Set the vertex and face information */ eNew->Org=eOrg->Dst; eNewSym->Org=eDst->Org; eNew->Lface=eNewSym->Lface=eOrg->Lface; /* Make sure the old face points to a valid half-edge */ eOrg->Lface->anEdge=eNewSym; if (!joiningLoops) { GLUface* newFace=allocFace(); if (newFace==NULL) { return NULL; } /* We split one loop into two -- the new loop is eNew->Lface */ MakeFace(newFace, eNew, eOrg->Lface); } return eNew; }
void Subdivision::InsertSite(const Point2d& x) // Inserts a new point into a subdivision representing a Delaunay // triangulation, and fixes the affected edges so that the result // is still a Delaunay triangulation. This is based on the // pseudocode from Guibas and Stolfi (1985) p.120, with slight // modifications and a bug fix. { Edge* e = Locate(x); if ((x == e->Org2d()) || (x == e->Dest2d())) // point is already in return; else if (OnEdge(x, e)) { e = e->Oprev(); DeleteEdge(e->Onext()); } // Connect the new point to the vertices of the containing // triangle (or quadrilateral, if the new point fell on an // existing edge.) Edge* base = MakeEdge(); base->EndPoints(e->Org(), new Point2d(x)); Splice(base, e); startingEdge = base; do { base = Connect(e, base->Sym()); e = base->Oprev(); } while (e->Lnext() != startingEdge); // Examine suspect edges to ensure that the Delaunay condition // is satisfied. do { Edge* t = e->Oprev(); if (RightOf(t->Dest2d(), e) && InCircle(e->Org2d(), t->Dest2d(), e->Dest2d(), x)) { Swap(e); e = e->Oprev(); } else if (e->Onext() == startingEdge) // no more suspect edges return; else // pop a suspect edge e = e->Onext()->Lprev(); } while (TRUE); }
/* tessMeshConnect (eOrg, eDst) creates a new edge from eOrg->Dst * to eDst->Org, and returns the corresponding half-edge eNew. * If eOrg->Lface == eDst->Lface, this splits one loop into two, * and the newly created loop is eNew->Lface. Otherwise, two disjoint * loops are merged into one, and the loop eDst->Lface is destroyed. * * If (eOrg == eDst), the new face will have only two edges. * If (eOrg->Lnext == eDst), the old face is reduced to a single edge. * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges. */ THalfEdge *tessMeshConnect (TMesh *mesh, THalfEdge *eOrg, THalfEdge *eDst) { THalfEdge *eNewSym; int joiningLoops = false; THalfEdge *eNew = MakeEdge (mesh, eOrg) ; if (eNew == NULL) return NULL; eNewSym = eNew->Sym; if (eDst->Lface != eOrg->Lface) { /* We are connecting two disjoint loops -- destroy eDst->Lface */ joiningLoops = true; KillFace (mesh, eDst->Lface, eOrg->Lface) ; } /* Connect the new edge appropriately */ Splice(eNew, eOrg->Lnext) ; Splice(eNewSym, eDst) ; /* Set the vertex and face information */ eNew->pOrigin = eOrg->Dst; eNewSym->pOrigin = eDst->pOrigin; eNew->Lface = eNewSym->Lface = eOrg->Lface; /* Make sure the old face points to a valid half-edge */ eOrg->Lface->pHalfEdge = eNewSym; if (! joiningLoops) { TFace *newFace= (TFace*)BucketAlloc (mesh->pFaceBucket) ; if (newFace == NULL) return NULL; /* We split one loop into two -- the new loop is eNew->Lface */ MakeFace (newFace, eNew, eOrg->Lface) ; } return eNew; }
/* tessMeshAddEdgeVertex( eOrg ) creates a new edge eNew such that * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. * eOrg and eNew will have the same left face. */ TESShalfEdge *tessMeshAddEdgeVertex( TESSmesh *mesh, TESShalfEdge *eOrg ) { TESShalfEdge *eNewSym; TESShalfEdge *eNew = MakeEdge( mesh, eOrg ); if (eNew == NULL) return NULL; eNewSym = eNew->Sym; /* Connect the new edge appropriately */ Splice( eNew, eOrg->Lnext ); /* Set the vertex and face information */ eNew->Org = eOrg->Dst; { TESSvertex *newVertex= (TESSvertex*)bucketAlloc( mesh->vertexBucket ); if (newVertex == NULL) return NULL; MakeVertex( newVertex, eNewSym, eNew->Org ); } eNew->Lface = eNewSym->Lface = eOrg->Lface; return eNew; }
/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ TESShalfEdge *tessMeshMakeEdge( TESSmesh *mesh ) { TESSvertex *newVertex1 = (TESSvertex*)bucketAlloc(mesh->vertexBucket); TESSvertex *newVertex2 = (TESSvertex*)bucketAlloc(mesh->vertexBucket); TESSface *newFace = (TESSface*)bucketAlloc(mesh->faceBucket); TESShalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { if (newVertex1 != NULL) bucketFree( mesh->vertexBucket, newVertex1 ); if (newVertex2 != NULL) bucketFree( mesh->vertexBucket, newVertex2 ); if (newFace != NULL) bucketFree( mesh->faceBucket, newFace ); return NULL; } e = MakeEdge( mesh, &mesh->eHead ); if (e == NULL) return NULL; MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh ) { GLUvertex *newVertex1= allocVertex(); GLUvertex *newVertex2= allocVertex(); GLUface *newFace= allocFace(); GLUhalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { if (newVertex1 != NULL) memFree(newVertex1); if (newVertex2 != NULL) memFree(newVertex2); if (newFace != NULL) memFree(newFace); return NULL; } e = MakeEdge( &mesh->eHead ); if (e == NULL) return NULL; MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ THalfEdge *tessMeshMakeEdge(TMesh *pMesh) { TVertex *newVertex1 = (TVertex*)BucketAlloc(pMesh->pVertexBucket); TVertex *newVertex2 = (TVertex*)BucketAlloc(pMesh->pVertexBucket); TFace *newFace = (TFace*)BucketAlloc(pMesh->pFaceBucket); THalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { if (newVertex1 != NULL) BucketFree (pMesh->pVertexBucket, newVertex1) ; if (newVertex2 != NULL) BucketFree (pMesh->pVertexBucket, newVertex2) ; if (newFace != NULL) BucketFree (pMesh->pFaceBucket, newFace) ; return NULL; } e = MakeEdge (pMesh, &pMesh->eHead) ; if (e == NULL) return NULL; MakeVertex (newVertex1, e, &pMesh->vHead) ; MakeVertex (newVertex2, e->Sym, &pMesh->vHead) ; MakeFace (newFace, e, &pMesh->fHead) ; return e; }
Graph* MakeGraph () { Graph *G = malloc (sizeof (Graph)); int i, S, Des, Val, W, Val1, Val2; Vertex *TempV = NULL; printf ("How many vertices: "); scanf ("%d", &(G -> NoOfV)); G -> V = malloc (sizeof (Vertex *) * (G -> NoOfV)); printf ("Automatic numbering - "); for (i = 0; i < (G -> NoOfV); ++i) { printf ("%d ", i); TempV = MakeVertex (i); if (TempV == NULL) { fprintf (stderr, "Error creating vertex."); return NULL; } G -> V[i] = TempV; } printf ("How many edges: "); scanf ("%d", &(G -> NoOfE)); G -> E = malloc (sizeof (Edge *) * (G -> NoOfE)); printf ("Directed(1) or Undirected(0): "); scanf ("%d", &(G -> Dir)); printf ("Weighted(1) or Unweighted(0): "); scanf ("%d", &(G -> Wt)); if ((G -> Dir)) { for (i = 0; i < (G -> NoOfE); i++) { W = 0; printf ("\nEdge %d ", i + 1); printf ("\nEnter Source: "); scanf ("%d", &S); printf ("\nEnter destination: "); scanf ("%d", &Des); if (S > G -> NoOfV || Des > G -> NoOfV) { fprintf (stderr, "\nInvalid Source or Destination try again!"); i--; continue; } if ((G -> Wt)) { printf ("\nEnter weight: "); scanf ("%d", &W); } Val = InsertAdj (G -> V[S], G -> V[Des], W); if (Val == -1) { fprintf (stderr, "\nError making adjacency list."); i--; continue; } else G -> E[i] = MakeEdge (G -> V[S], G -> V[Des], W); } } else { for (i = 0; i < (G -> NoOfE); i++) { W = 0; printf ("\nEdge %d: ", i + 1); printf ("\nEnter first Vertex: "); scanf ("%d", &S); printf ("\nEnter second Vertex: "); scanf ("%d", &Des); if (S > G -> NoOfV || Des > G -> NoOfV) { fprintf (stderr, "\nInvalid Source or Destination try again!"); i--; continue; } if ((G -> Wt)) { printf ("\nEnter weight: "); scanf ("%d", &W); } Val1 = InsertAdj (G -> V[S], G -> V[Des], W); Val2 = InsertAdj (G -> V[Des], G -> V[S], W); if (Val1 == -1 || Val2 == -1) { fprintf (stderr, "\nError making adjacency list."); i--; continue; } else G -> E[i] = MakeEdge (G -> V[S], G -> V[Des], W); } } /* printf ("All data are as follows: \n"); for (i = 0; i < (G -> NoOfV); i++) PrintVertexData(G -> V[i]); for (i = 0; i < (G -> NoOfE); i++) PrintEdgeData(G -> E[i]); */ return G; }