Пример #1
0
/*---------------------------------------------------------------------
 DoubleTriangle builds the initial double triangle.  It first finds 3 
 noncollinear points and makes two faces out of them, in opposite order.
 It then finds a fourth point that is not coplanar with that face.  The  
 vertices are stored in the face structure in counterclockwise order so 
 that the volume between the face and the point is negative. Lastly, the
 3 newfaces to the fourth point are constructed and the data structures
 are cleaned up. 
---------------------------------------------------------------------*/
void    DoubleTriangle( void )
{
   tVertex  v0, v1, v2, v3;
   tFace    f0, f1 = NULL;
   int      vol;
	
   /* Find 3 noncollinear points. */
   v0 = vertices;
   while ( Collinear( v0, v0->next, v0->next->next ) )
      if ( ( v0 = v0->next ) == vertices )
         printf("DoubleTriangle:  All points are Collinear!\n"), exit(0);
   v1 = v0->next;
   v2 = v1->next;
	
   /* Mark the vertices as processed. */
   v0->mark = PROCESSED;
   v1->mark = PROCESSED;
   v2->mark = PROCESSED;
   
   /* Create the two "twin" faces. */
   f0 = MakeFace( v0, v1, v2, f1 );
   f1 = MakeFace( v2, v1, v0, f0 );

   /* Link adjacent face fields. */
   f0->edge[0]->adjface[1] = f1;
   f0->edge[1]->adjface[1] = f1;
   f0->edge[2]->adjface[1] = f1;
   f1->edge[0]->adjface[1] = f0;
   f1->edge[1]->adjface[1] = f0;
   f1->edge[2]->adjface[1] = f0;
	
   /* Find a fourth, noncoplanar point to form tetrahedron. */
   v3 = v2->next;
   vol = VolumeSign( f0, v3 );
   while ( !vol )   {
      if ( ( v3 = v3->next ) == v0 ) 
         printf("DoubleTriangle:  All points are coplanar!\n"), exit(0);
      vol = VolumeSign( f0, v3 );
   }
	
   /* Insure that v3 will be the first added. */
   vertices = v3;
   if ( debug ) {
      fprintf(stderr, "DoubleTriangle: finished. Head repositioned at v3.\n");
      PrintOut( vertices );
   }

	
}
Пример #2
0
/*---------------------------------------------------------------------
Convexity checks that the volume between every face and every
point is negative.  This shows that each point is inside every face
and 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");
}
Пример #3
0
char SegTriCross( tPointi T, tPointd q, tPointd r )
{
   int vol0, vol1, vol2;
   
   vol0 = VolumeSign( q, Vertices[ T[0] ], Vertices[ T[1] ], r ); 
   vol1 = VolumeSign( q, Vertices[ T[1] ], Vertices[ T[2] ], r ); 
   vol2 = VolumeSign( q, Vertices[ T[2] ], Vertices[ T[0] ], r );
 
     
   /* Same sign: segment intersects interior of triangle. */
   if ( ( ( vol0 > 0 ) && ( vol1 > 0 ) && ( vol2 > 0 ) ) || 
        ( ( vol0 < 0 ) && ( vol1 < 0 ) && ( vol2 < 0 ) ) )
      return 'f';
   
   /* Opposite sign: no intersection between segment and triangle */
   if ( ( ( vol0 > 0 ) || ( vol1 > 0 ) || ( vol2 > 0 ) ) &&
        ( ( vol0 < 0 ) || ( vol1 < 0 ) || ( vol2 < 0 ) ) )
      return '0';

   else if ( ( vol0 == 0 ) && ( vol1 == 0 ) && ( vol2 == 0 ) )
     return '0';
   
   /* Two zeros: segment intersects vertex. */
   else if ( ( ( vol0 == 0 ) && ( vol1 == 0 ) ) || 
             ( ( vol0 == 0 ) && ( vol2 == 0 ) ) || 
             ( ( vol1 == 0 ) && ( vol2 == 0 ) ) )
      return 'v';

   /* One zero: segment intersects edge. */
   else if ( ( vol0 == 0 ) || ( vol1 == 0 ) || ( vol2 == 0 ) )
      return 'e';
   
   else
     fprintf( stderr, "Error 2 in SegTriCross\n" );

   return '0';
}
char SegmentTriangleIntersection::SegTriCross( tPointi T, tPointd q, tPointd r )
{
    double vol0, vol1, vol2;

    vol0 = VolumeSign( q, Vertices[ T[0] ], Vertices[ T[1] ], r );
    vol1 = VolumeSign( q, Vertices[ T[1] ], Vertices[ T[2] ], r );
    vol2 = VolumeSign( q, Vertices[ T[2] ], Vertices[ T[0] ], r );

    //printf( "SegTriCross:  vol0 = %f; vol1 = %f; vol2 = %f\n", vol0, vol1, vol2 );

    /* Same sign: segment intersects interior of triangle. */
    if ( ( ( vol0 > 0 ) && ( vol1 > 0 ) && ( vol2 > 0 ) ) ||
            ( ( vol0 < 0 ) && ( vol1 < 0 ) && ( vol2 < 0 ) ) )
        return 'f';

    /* Opposite sign: no intersection between segment and triangle */
    if ( ( ( vol0 > 0 ) || ( vol1 > 0 ) || ( vol2 > 0 ) ) &&
            ( ( vol0 < 0 ) || ( vol1 < 0 ) || ( vol2 < 0 ) ) )
        return '0';

    else if ( ( vol0 == 0 ) && ( vol1 == 0 ) && ( vol2 == 0 ) )
        fprintf( stderr, "Error 1 in SegTriCross\n" ), exit(EXIT_FAILURE);

    /* Two zeros: segment intersects vertex. */
    else if ( ( ( vol0 == 0 ) && ( vol1 == 0 ) ) ||
              ( ( vol0 == 0 ) && ( vol2 == 0 ) ) ||
              ( ( vol1 == 0 ) && ( vol2 == 0 ) ) )
        return 'v';

    /* One zero: segment intersects edge. */
    else if ( ( vol0 == 0 ) || ( vol1 == 0 ) || ( vol2 == 0 ) )
        return 'e';

    else
        fprintf( stderr, "Error 2 in SegTriCross\n" ), exit(EXIT_FAILURE);
}
Пример #5
0
/*---------------------------------------------------------------------
AddOne is passed a vertex.  It first determines all faces visible from 
that point.  If none are visible then the point is marked as not 
onhull.  Next is a loop over edges.  If both faces adjacent to an edge
are visible, then the edge is marked for deletion.  If just one of the
adjacent faces is visible then a new face is constructed.
---------------------------------------------------------------------*/
int 	AddOne( tVertex p )
{
   tFace  f; 
   tEdge  e, temp;
   int 	  vol;
   int	  vis = FALSE;

   if ( debug ) {
      fprintf(stderr, "AddOne: starting to add v%d.\n", p->vnum);
      PrintOut( vertices );
   }

   /* Mark faces visible from p. */
   f = faces;
   do {
      vol = VolumeSign( f, p );
      if (debug) fprintf(stderr, 
         "faddr: %p   paddr: %p   Vol = %d\n", f,p,vol);
      if ( vol < 0 ) {
	 f->visible = VISIBLE;  
	 vis = TRUE;                      
      }
      f = f->next;
   } while ( f != faces );

   /* If no faces are visible from p, then p is inside the hull. */
   if ( !vis ) {
     p->onhull = !ONHULL;  
      return FALSE; 
   }

   /* Mark edges in interior of visible region for deletion.
      Erect a newface based on each border edge. */
   e = edges;
   do {
      temp = e->next;
      if ( e->adjface[0]->visible && e->adjface[1]->visible )
	 /* e interior: mark for deletion. */
	 e->deleted = REMOVED;
      else if ( e->adjface[0]->visible || e->adjface[1]->visible ) 
	 /* e border: make a new face. */
	 e->newface = MakeConeFace( e, p );
      e = temp;
   } while ( e != edges );
   return TRUE;
}
Пример #6
0
int chIsPointInside(int pos[])
{
  int s = 1;
  struct tVertexStructure p;
  tFace f;

  if(faces == NULL) return 0;

  p.v[X] = pos[0];
  p.v[Y] = pos[1];
  p.v[Z] = pos[2];

  f = faces;
  do 
    {
      if(VolumeSign(f,&p) < 0) s = 0;
      f  = f ->next;
    } 
  while(s==1 && f!=faces);

  return s;
}