⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chull.c

📁 求三维凸包的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	      f,p->vnum,voli,vol);   /* The volume should be an integer. */   if      ( vol > 0.5 )   return  1;   else if ( vol < -0.5 )  return -1;   else                    return  0;}/*-------------------------------------------------------------------*/void	PrintPoint( tVertex p ){   int	i;   for ( i = 0; i < 3; i++ )      printf("\t%d", p->v[i]);   putchar('\n');}/*---------------------------------------------------------------------MakeConeFace makes a new face and two new edges between the edge and the point that are passed to it. It returns a pointer tothe new face.---------------------------------------------------------------------*/tFace	MakeConeFace( tEdge e, tVertex p ){   tEdge  new_edge[2];   tFace  new_face;   int 	  i, j;   /* Make two new edges (if don't already exist). */   for ( i=0; i < 2; ++i )       /* If the edge exists, copy it into new_edge. */      if ( !( new_edge[i] = e->endpts[i]->duplicate) ) {	 /* Otherwise (duplicate is NULL), MakeNullEdge. */	 new_edge[i] = MakeNullEdge();	 new_edge[i]->endpts[0] = e->endpts[i];	 new_edge[i]->endpts[1] = p;	 e->endpts[i]->duplicate = new_edge[i];      }   /* Make the new face. */   new_face = MakeNullFace();      new_face->edge[0] = e;   new_face->edge[1] = new_edge[0];   new_face->edge[2] = new_edge[1];   MakeCcw( new_face, e, p );            /* Set the adjacent face pointers. */   for ( i=0; i < 2; ++i )      for ( j=0; j < 2; ++j )  	 /* Only one NULL link should be set to new_face. */	 if ( !new_edge[i]->adjface[j] ) {	    new_edge[i]->adjface[j] = new_face;	    break;	 }           return new_face;}/*---------------------------------------------------------------------MakeCcw puts the vertices in the face structure in counterclock wise order.  We want to store the vertices in the same order as in the visible face.  The third vertex is always p.---------------------------------------------------------------------*/void	MakeCcw( tFace f, tEdge e, tVertex p ){   tFace  fv;   /* The visible face adjacent to e */   int    i;    /* Index of e->endpoint[0] in fv. */   tEdge  s;	/* Temporary, for swapping */         if  ( e->adjface[0]->visible )              fv = e->adjface[0];   else fv = e->adjface[1];          /* Set vertex[0] & [1] of f to have the same orientation      as do the corresponding vertices of fv. */    for ( i=0; fv->vertex[i] != e->endpts[0]; ++i )      ;   /* Orient f the same as fv. */   if ( fv->vertex[ (i+1) % 3 ] != e->endpts[1] ) {      f->vertex[0] = e->endpts[1];        f->vertex[1] = e->endpts[0];       }   else {                                     f->vertex[0] = e->endpts[0];         f->vertex[1] = e->endpts[1];            SWAP( s, f->edge[1], f->edge[2] );   }   /* This swap is tricky. e is edge[0]. edge[1] is based on endpt[0],      edge[2] on endpt[1].  So if e is oriented "forwards," we      need to move edge[1] to follow [0], because it precedes. */      f->vertex[2] = p;} /*---------------------------------------------------------------------MakeNullEdge creates a new cell and initializes all pointers to NULLand sets all flags to off.  It returns a pointer to the empty cell.---------------------------------------------------------------------*/tEdge 	MakeNullEdge( void ){   tEdge  e;   NEW( e, tsEdge );   e->adjface[0] = e->adjface[1] = e->newface = NULL;   e->endpts[0] = e->endpts[1] = NULL;   e->delete = !REMOVED;   ADD( edges, e );   return e;}/*--------------------------------------------------------------------MakeNullFace creates a new face structure and initializes all of itsflags to NULL and sets all the flags to off.  It returns a pointerto the empty cell.---------------------------------------------------------------------*/tFace 	MakeNullFace( void ){   tFace  f;   int    i;   NEW( f, tsFace);   for ( i=0; i < 3; ++i ) {      f->edge[i] = NULL;      f->vertex[i] = NULL;   }   f->visible = !VISIBLE;   ADD( faces, f );   return f;}/*---------------------------------------------------------------------MakeFace creates a new face structure from three vertices (in ccworder).  It returns a pointer to the face.---------------------------------------------------------------------*/tFace   MakeFace( tVertex v0, tVertex v1, tVertex v2, tFace fold ){   tFace  f;   tEdge  e0, e1, e2;   /* Create edges of the initial triangle. */   if( !fold ) {     e0 = MakeNullEdge();     e1 = MakeNullEdge();     e2 = MakeNullEdge();   }   else { /* Copy from fold, in reverse order. */     e0 = fold->edge[2];     e1 = fold->edge[1];     e2 = fold->edge[0];   }   e0->endpts[0] = v0;              e0->endpts[1] = v1;   e1->endpts[0] = v1;              e1->endpts[1] = v2;   e2->endpts[0] = v2;              e2->endpts[1] = v0;	   /* Create face for triangle. */   f = MakeNullFace();   f->edge[0]   = e0;  f->edge[1]   = e1; f->edge[2]   = e2;   f->vertex[0] = v0;  f->vertex[1] = v1; f->vertex[2] = v2;	   /* Link edges to face. */   e0->adjface[0] = e1->adjface[0] = e2->adjface[0] = f;	   return f;}/*---------------------------------------------------------------------CleanUp goes through each data structure list and clears allflags and NULLs out some pointers.  The order of processing(edges, faces, vertices) is important.---------------------------------------------------------------------*/void	CleanUp( void ){   CleanEdges();   CleanFaces();   CleanVertices();}/*---------------------------------------------------------------------CleanEdges runs through the edge list and cleans up the structure.If there is a newface then it will put that face in place of the visible face and NULL out newface. It also deletes so marked edges.---------------------------------------------------------------------*/void	CleanEdges( void ){   tEdge  e;	/* Primary index into edge list. */   tEdge  t;	/* Temporary edge pointer. */		   /* Integrate the newface's into the data structure. */   /* Check every edge. */   e = edges;   do {      if ( e->newface ) { 	 if ( e->adjface[0]->visible )	    e->adjface[0] = e->newface; 	 else	e->adjface[1] = e->newface;	 e->newface = NULL;      }      e = e->next;   } while ( e != edges );   /* Delete any edges marked for deletion. */   while ( edges && edges->delete ) {       e = edges;      DELETE( edges, e );   }   e = edges->next;   do {      if ( e->delete ) {	 t = e;	 e = e->next;	 DELETE( edges, t );      }      else e = e->next;   } while ( e != edges );}/*---------------------------------------------------------------------CleanFaces runs through the face list and deletes any face marked visible.---------------------------------------------------------------------*/void	CleanFaces( void ){   tFace  f;	/* Primary pointer into face list. */   tFace  t;	/* Temporary pointer, for deleting. */	   while ( faces && faces->visible ) {       f = faces;      DELETE( faces, f );   }   f = faces->next;   do {      if ( f->visible ) {	 t = f;	 f = f->next;	 DELETE( faces, t );      }      else f = f->next;   } while ( f != faces );}/*---------------------------------------------------------------------CleanVertices runs through the vertex list and deletes the vertices that are marked as processed but are not incident to any undeleted edges. ---------------------------------------------------------------------*/void	CleanVertices( void ){   tEdge    e;   tVertex  v, t;	   /* Mark all vertices incident to some undeleted edge as on the hull. */   e = edges;   do {      e->endpts[0]->onhull = e->endpts[1]->onhull = ONHULL;      e = e->next;   } while (e != edges);	   /* Delete all vertices that have been processed but      are not on the hull. */   while ( vertices && vertices->mark && !vertices->onhull ) {       v = vertices;      DELETE( vertices, v );   }   v = vertices->next;   do {      if ( v->mark && !v->onhull ) {    	 t = v; 	 v = v->next;	 DELETE( vertices, t )      }      else v = v->next;   } while ( v != vertices );	   /* Reset flags. */   v = vertices;   do {      v->duplicate = NULL;       v->onhull = !ONHULL;       v = v->next;   } while ( v != vertices );}/*---------------------------------------------------------------------Collinear checks to see if the three points given are collinear,by checking to see if each element of the cross product is zero.---------------------------------------------------------------------*/bool	Collinear( tVertex a, tVertex b, tVertex c ){   return          ( c->v[Z] - a->v[Z] ) * ( b->v[Y] - a->v[Y] ) -         ( b->v[Z] - a->v[Z] ) * ( c->v[Y] - a->v[Y] ) == 0      && ( b->v[Z] - a->v[Z] ) * ( c->v[X] - a->v[X] ) -         ( b->v[X] - a->v[X] ) * ( c->v[Z] - a->v[Z] ) == 0      && ( b->v[X] - a->v[X] ) * ( c->v[Y] - a->v[Y] ) -         ( b->v[Y] - a->v[Y] ) * ( c->v[X] - a->v[X] ) == 0  ;}/*---------------------------------------------------------------------Consistency runs through the edge list and checks that alladjacent faces have their endpoints in opposite order.  This verifiesthat the vertices are in counterclockwise order.---------------------------------------------------------------------*/void	Consistency( void ){   register tEdge  e;   register int    i, j;   e = edges;   do {      /* find index of endpoint[0] in adjacent face[0] */      for ( i = 0; e->adjface[0]->vertex[i] != e->endpts[0]; ++i )	 ;         /* find index of endpoint[0] in adjacent face[1] */      for ( j = 0; e->adjface[1]->vertex[j] != e->endpts[0]; ++j )	 ;      /* check if the endpoints occur in opposite order */      if ( !( e->adjface[0]->vertex[ (i+1) % 3 ] ==	      e->adjface[1]->vertex[ (j+2) % 3 ] ||	      e->adjface[0]->vertex[ (i+2) % 3 ] ==	      e->adjface[1]->vertex[ (j+1) % 3 ] )  )	 break;      e = e->next;   } while ( e != edges );   if ( e != edges )      fprintf( stderr, "Checks: edges are NOT consistent.\n");   else      fprintf( stderr, "Checks: edges consistent.\n");}/*---------------------------------------------------------------------Convexity checks that the volume between every face and everypoint is negative.  This shows that each point is inside every faceand therefore the hull is convex.---------------------------------------------------------------------*/void	Convexity( void ){   register tFace    f;   register tVertex  v;   int               vol;   f = faces;      do {      v = vertices;      do {	 if ( v->mark ) {	    vol = VolumeSign( f, v );	    if ( vol < 0 )	       break;	 }	 v = v->next;      } while ( v != vertices );      f = f->next;   } while ( f != faces );   if ( f != faces )      fprintf( stderr, "Checks: NOT convex.\n");   else if ( check )       fprintf( stderr, "Checks: convex.\n");}/*---------------------------------------------------------------------CheckEuler checks Euler's relation, as well as its implications whenall faces are known to be triangles.  Only prints positive informationwhen debug is true, but always prints negative information.---------------------------------------------------------------------*/void	CheckEuler( int V, int E, int F ){   if ( check )      fprintf( stderr, "Checks: V, E, F = %d %d %d:\t", V, E, F);   if ( (V - E + F) != 2 )      fprintf( stderr, "Checks: V-E+F != 2\n");   else if ( check )      fprintf( stderr, "V-E+F = 2\t");   if ( F != (2 * V - 4) )      fprintf( stderr, "Checks: F=%d != 2V-4=%d; V=%d\n",	      F, 2*V-4, V);   else if ( check )       fprintf( stderr, "F = 2V-4\t");      if ( (2 * E) != (3 * F) )      fprintf( stderr, "Checks: 2E=%d != 3F=%d; E=%d, F=%d\n",	      2*E, 3*F, E, F );   else if ( check )       fprintf( stderr, "2E = 3F\n");}/*-------------------------------------------------------------------*/void	Checks( void ){   tVertex  v;   tEdge    e;   tFace    f;   int 	   V = 0, E = 0 , F = 0;   Consistency();   Convexity();   if ( v = vertices )      do {         if (v->mark) V++;	 v = v->next;      } while ( v != vertices );   if ( e = edges )      do {         E++;	 e = e->next;      } while ( e != edges );   if ( f = faces )      do {         F++;	 f  = f ->next;      } while ( f  != faces );   CheckEuler( V, E, F );}/*===================================================================These functions are used whenever the debug flag is set.They print out the entire contents of each data structure.  Printing is to standard error.  To grab the output in a file in the csh, use this:	chull < i.file >&! o.file=====================================================================*//*-------------------------------------------------------------------*/void	PrintOut( tVertex v ){   fprintf( stderr, "\nHead vertex %d = %6x :\n", v->vnum, v );   PrintVertices();   PrintEdges();   PrintFaces();}/*-------------------------------------------------------------------*/void	PrintVertices( void ){   tVertex  temp;   temp = vertices;   fprintf (stderr, "Vertex List\n");   if (vertices) do {      fprintf(stderr,"  addr %6x\t", vertices );      fprintf(stderr,"  vnum %4d", vertices->vnum );      fprintf(stderr,"   (%6d,%6d,%6d)",vertices->v[X],	      vertices->v[Y], vertices->v[Z] );      fprintf(stderr,"   active:%3d", vertices->onhull );      fprintf(stderr,"   dup:%5x", vertices->duplicate );      fprintf(stderr,"   mark:%2d\n", vertices->mark );      vertices = vertices->next;   } while ( vertices != temp );}/*-------------------------------------------------------------------*/void	PrintEdges( void ){   tEdge  temp;   int 	  i;	   temp = edges;   fprintf (stderr, "Edge List\n");   if (edges) do {      fprintf( stderr, "  addr: %6x\t", edges );      fprintf( stderr, "adj: ");      for (i=0; i<2; ++i) 	 fprintf( stderr, "%6x", edges->adjface[i] );      fprintf( stderr, "  endpts:");      for (i=0; i<2; ++i) 	 fprintf( stderr, "%4d", edges->endpts[i]->vnum);      fprintf( stderr, "  del:%3d\n", edges->delete );      edges = edges->next;    } while (edges != temp );}/*-------------------------------------------------------------------*/void	PrintFaces( void ){   int 	  i;   tFace  temp;   temp = faces;   fprintf (stderr, "Face List\n");   if (faces) do {      fprintf(stderr, "  addr: %6x\t", faces );      fprintf(stderr, "  edges:");      for( i=0; i<3; ++i )	 fprintf(stderr, "%6x", faces->edge[i] );      fprintf(stderr, "  vert:");      for ( i=0; i<3; ++i)	 fprintf(stderr, "%4d", faces->vertex[i]->vnum );      fprintf(stderr, "  vis: %d\n", faces->visible );      faces= faces->next;   } while ( faces != temp );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -