Пример #1
0
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;
}
Пример #2
0
/* 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;
}
Пример #3
0
/* __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;
}
Пример #4
0
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;
}
Пример #5
0
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++;
}
Пример #6
0
/* __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;
}
Пример #7
0
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);
}
Пример #8
0
/* 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;
}
Пример #9
0
/* 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;
}
Пример #10
0
/* 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;
}
Пример #11
0
/* __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;
}
Пример #12
0
/* 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;
}
Пример #13
0
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;
}