📄 create.c
字号:
} /* create two vertex-uses, one for each end of edge */ vu = (VertexUse*)malloc(sizeof(VertexUse)); vu->vua = NULL; vu->v = v2; vu->vuPrev = vu2; vu->vuNext = vu2->vuNext; vu2->vuNext->vuPrev = vu; vu2->vuNext = vu; vum = (VertexUse*)malloc(sizeof(VertexUse)); vum->vua = NULL; vum->v = v1; vum->vuPrev = vu1; vum->vuNext = vu1->vuNext; vu1->vuNext->vuPrev = vum; vu1->vuNext = vum; /* create edge and two edge-uses, one for each side of edge */ eu1 = vu1->eu; eu2 = vu2->eu; e = (Edge*)malloc(sizeof(Edge)); e->ea = NULL; e->eu = eu = (EdgeUse*)malloc(sizeof(EdgeUse)); eu->eua = NULL; e->fixed = 0; eum = (EdgeUse*)malloc(sizeof(EdgeUse)); eum->eua = NULL; eu->e = eum->e = e; eu->vu = vu; vu->eu = eu; eum->vu = vum; vum->eu = eum; eu->euMate = eum; eum->euMate = eu; eu->euCW = eu1; eu->euCCW = eu2->euCCW; eum->euCW = eu2; eum->euCCW = eu1->euCCW; eu1->euCCW->euCW = eum; eu2->euCCW->euCW = eu; eu1->euCCW = eu; eu2->euCCW = eum; /* create a face */ f = eu1->f; fm = (Face*)malloc(sizeof(Face)); fm->fa = NULL; fm->eu = eum; fm->fPrev = f; fm->fNext = f->fNext; f->fNext->fPrev = fm; f->fNext = fm; fm->m = f->m; /* make all edge-uses owned by the appropriate faces */ f->eu = eu1; eu->f = f; eum->f = fm; for (eut=eu2; eut->f!=fm; eut=eut->euCW) eut->f = fm; /* set output values */ *enew = e; *fnew = fm;}void makeEdgeVertex (Vertex *v1, float x, float y, Face *f, Edge **enew, Vertex **vnew)/******************************************************************************makeEdgeVertex - Create an edge connecting an existing vertex (v1) to a new vertex (with coordinates x,y) in a specified face f. Return the new edge and the new vertex.*******************************************************************************Input:v1 existing Vertexx x-coordinate of new vertexy y-coordinate of new vertexf specified FaceOutput:enew new Edgevnew new Vertex*******************************************************************************Author: Dave Hale, Colorado School of Mines, 07/09/90******************************************************************************/{ Vertex *v; VertexUse *vu,*vum,*vu1; Edge *e; EdgeUse *eu,*eum,*eu1; /* determine which use of vertex v1 is adjacent to face f */ for (vu1=v1->vu; vu1->eu->f!=f; vu1=vu1->vuNext); /* create a new vertex and vertex-use */ v = (Vertex*)malloc(sizeof(Vertex)); v->va = NULL; vu = (VertexUse*)malloc(sizeof(VertexUse)); vu->vua = NULL; v->x = x; v->y = y; v->fixed = 0; v->vu = vu; vu->v = v; vu->vuNext = vu->vuPrev = vu; /* create a new vertex-use for existing vertex */ vum = (VertexUse*)malloc(sizeof(VertexUse)); vum->vua = NULL; vum->v = v1; vum->vuPrev = vu1; vum->vuNext = vu1->vuNext; vu1->vuNext->vuPrev = vum; vu1->vuNext = vum; /* create edge and two edge-uses, one for each side of edge */ eu1 = vu1->eu; e = (Edge*)malloc(sizeof(Edge)); e->ea = NULL; e->eu = eu = (EdgeUse*)malloc(sizeof(EdgeUse)); eu->eua = NULL; e->fixed = 0; eum = (EdgeUse*)malloc(sizeof(EdgeUse)); eum->eua = NULL; eu->e = eum->e = e; eu->f = eum->f = f; eu->vu = vu; vu->eu = eu; eum->vu = vum; vum->eu = eum; eu->euMate = eum; eum->euMate = eu; eu->euCW = eu1; eu->euCCW = eum; eum->euCW = eu; eum->euCCW = eu1->euCCW; eu1->euCCW->euCW = eum; eu1->euCCW = eu; /* set output values */ *enew = e; *vnew = v;}Vertex *addVertexToModel (Model *m, float x, float y)/*****************************************************************************addVertexToModel - Add a vertex to model, and return pointer to new vertex******************************************************************************Input:m modelx x-coordinate of new vertexy y-coordinate of new vertex******************************************************************************Notes:If the new vertex is close to an existing vertex, this function returns NULL.******************************************************************************Author: Dave Hale, Colorado School of Mines, 07/09/90******************************************************************************/{ int first,fixed=0; Vertex *v,*vo,*v1,*v2,*v3,*v1fixed=NULL,*v2fixed=NULL; VertexUse *vu; Edge *e,*e1,*e2,*e3,*eb=NULL; EdgeUse *eu,*euo; Face *f,*fs,*f1,*f2,*f3; /* find existing vertex nearest to new vertex */ v = nearestVertexInModel(m,NULL,x,y); /* if new vertex is too close to existing vertex, return existing */ if (sqrt((v->x-x)*(v->x-x)+(v->y-y)*(v->y-y))<m->eps) return NULL; /* find triangle that contains new vertex */ f = (v->vu->eu->f!=NULL?v->vu->eu->f:v->vu->eu->euMate->f); f = insideTriInModel(m,f,x,y); /* if the edge nearest new vertex is a fixed edge and very nearby */ e = nearestEdgeInModel(m,f->eu->e,x,y); if (e->fixed && distanceToEdge(e,x,y)<m->eps) { /* remember the endpoints of the fixed edge */ v1fixed = e->eu->vu->v; v2fixed = e->eu->euCW->vu->v; /* unfix the fixed edge */ e->fixed = 0; /* project new vertex onto edge */ projectToEdge(e,&x,&y); /* remember edge was fixed */ fixed = 1; /* if edge is on boundary, remember to delete it later */ if (e->eu->f==NULL || e->eu->euMate->f==NULL) eb = e; } /* this triangle will be deleted */ if (m->tDel!=NULL) m->tDel(m,f); /* make edges from new vertex to vertices of this triangle */ vu = f->eu->vu; v1 = vu->v; v2 = vu->eu->euCW->vu->v; v3 = vu->eu->euCCW->vu->v; f1 = f; makeEdgeVertex(v1,x,y,f1,&e1,&v); makeEdgeFace(v2,v,&e2,&f2); makeEdgeFace(v3,v,&e3,&f3); /* 3 triangles were made */ if (m->tAdd!=NULL) { m->tAdd(m,f1); m->tAdd(m,f2); m->tAdd(m,f3); } /* compute circumcircles of the 3 new triangles */ vu = v->vu; do { circumTri(vu->eu->f); vu = vu->vuNext; } while (vu!=v->vu); /* loop over vertex-uses (triangles) in clockwise direction */ vu = v->vu; first = 1; do { /* determine edge-uses and edge opposite new vertex */ eu = vu->eu->euCW; euo = eu->euMate; e = eu->e; /* if opposite triangle's circumcircle contains new vertex */ if (euo->f!=NULL && !euo->e->fixed && inCircumTri(x,y,euo->f)) { /* determine vertex opposite edge */ vo = euo->euCCW->vu->v; /* 2 triangles will be deleted */ if (m->tDel!=NULL) { m->tDel(m,e->eu->f); m->tDel(m,e->eu->euMate->f); } /* kill opposite edge */ killEdge(e,&fs); /* make edge connecting new and opposite vertices */ makeEdgeFace(v,vo,&e,&f); /* 2 triangles were created */ if (m->tAdd!=NULL) { m->tAdd(m,e->eu->f); m->tAdd(m,e->eu->euMate->f); } /* compute circumcircles of 2 new triangles */ circumTri(e->eu->f); circumTri(e->eu->euMate->f); /* else, go to next vertex-use (triangle) clockwise */ } else { vu = vu->eu->euCCW->euMate->vu; first = 0; } } while (vu!=v->vu || first); /* if new vertex was added on an edge that was fixed */ if (fixed) { /* loop over vertex uses of new vertex */ vu = v->vu; do { /* edge use */ eu = vu->eu; /* fix edge if it was part of fixed edge */ if (eu->euCCW->vu->v==v1fixed) eu->euCCW->e->fixed = 1; if (eu->euCW->vu->v==v2fixed) eu->e->fixed = 1; /* next vertex use */ vu = vu->vuNext; } while (vu!=v->vu); } /* if edge on boundary needs to be deleted, delete it */ if (eb!=NULL) killBoundaryEdge(eb); /* if specified, do add vertex function */ if (m->vAdd!=NULL) m->vAdd(m,v); /* debug */ /* checkModel(m); */ /* return pointer to vertex */ return v;}Tri* insideTriInModel (Model *m, Tri *start, float x, float y)/*****************************************************************************insideTriInModel - return pointer to triangle in model containing specified (x,y) coordinates******************************************************************************Input:m Modelstart triangle to look at first (NULL to begin looking anywhere)x x-coordinatey y-coordinate******************************************************************************Notes:Points on an edge of a triangle are assumed to be inside that triangle.An edge may be used by two triangles, so two triangles may "contain"a point that lies on an edge. The first triangle found to containthe specified point is returned.******************************************************************************Author: Dave Hale, Colorado School of Mines, 09/11/90******************************************************************************/{ int inside=0; float x1,y1,x2,y2,x3,y3,s1,s2; Vertex *v1,*v2,*v3; EdgeUse *eu; Tri *t; /* start at some face in model */ t = (start==NULL ? m->f : start); /* loop over triangles until point is inside */ while (!inside) { /* loop over all edge-uses in triangle */ eu = t->eu; do { /* vertices at ends of edge */ v1 = eu->vu->v; x1 = v1->x; y1 = v1->y; v2 = eu->euCW->vu->v; x2 = v2->x; y2 = v2->y; /* other vertex */ v3 = eu->euCCW->vu->v; x3 = v3->x; y3 = v3->y; /* cross-products */ s1 = (x2-x1)*(y3-y1)-(x3-x1)*(y2-y1); s2 = (x2-x1)*(y-y1)-(x-x1)*(y2-y1); /* if cross-products have different sign */ if (s1*s2<0.0) { /* if triangle opposite current edge exists */ if (eu->euMate->f!=NULL) { /* look at that triangle next */ t = eu->euMate->f; break; } } /* next edge-use */ eu = eu->euCW; } while (eu!=t->eu); /* if did not break, then point is inside triangle */ if (eu==t->eu) inside = 1; } /* return pointer to triangle containing point */ return t;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -