예제 #1
0
/*---------------------------------------------------------------------
    'p': The segment lies wholly within the plane.
    'q': The q endpoint is on the plane (but not 'p').
    'r': The r endpoint is on the plane (but not 'p').
    '0': The segment lies strictly to one side or the other of the plane.
    '1': The segement intersects the plane, and 'p' does not hold.
---------------------------------------------------------------------*/
char	SegPlaneInt( tPointi T, tPointd q, tPointd r, tPointd p, int *m)
{
    tPointd N; double d;
    tPointd rq;
    double num, denom, t;
    int i;

    *m = PlaneCoeff( T, N, &d );
    /*printf("m=%d; plane=(%lf,%lf,%lf,%lf)\n", m, N[X],N[Y],N[Z],d);*/
    num = d - Dot( q, N );
    SubVec( r, q, rq );
    denom = Dot( rq, N );
    /*printf("SegPlaneInt: num=%lf, denom=%lf\n", num, denom );*/

    if ( denom == 0.0 ) {  /* Segment is parallel to plane. */
       if ( num == 0.0 )   /* q is on plane. */
           return 'p';
       else
           return '0';
    }
    else
       t = num / denom;
    /*printf("SegPlaneInt: t=%lf \n", t );*/

    for( i = 0; i < DIM; i++ )
       p[i] = q[i] + t * ( r[i] - q[i] );

    if ( (0.0 < t) && (t < 1.0) )
         return '1';
    else if ( num == 0.0 )   /* t == 0 */
         return 'q';
    else if ( num == denom ) /* t == 1 */
         return 'r';
    else return '0';
}
예제 #2
0
/*---------------------------------------------------------------------
---------------------------------------------------------------------*/
void    ConvexIntersect( tPolygoni P, tPolygoni Q, int n, int m )
                           /* P has n vertices, Q has m vertices. */
{
   int     a, b;           /* indices on P and Q (resp.) */
   int     a1, b1;         /* a-1, b-1 (resp.) */
   tPointi A, B;           /* directed edges on P and Q (resp.) */
   int     cross;          /* sign of z-component of A x B */
   int     bHA, aHB;       /* b in H(A); a in H(b). */
   tPointi Origin = {0,0}; /* (0,0) */
   tPointd p;              /* double point of intersection */
   tPointd q;              /* second point of intersection */
   tInFlag inflag;         /* {Pin, Qin, Unknown}: which inside */
   int     aa, ba;         /* # advances on a & b indices (after 1st inter.) */
   bool    FirstPoint;     /* Is this the first point? (used to initialize).*/
   tPointd p0;             /* The first point. */
   int     code;           /* SegSegInt return code. */ 

   /* Initialize variables. */
   a = 0; b = 0; aa = 0; ba = 0;
   inflag = Unknown; FirstPoint = TRUE;

   do {
      /*printf("%%Before Advances:a=%d, b=%d; aa=%d, ba=%d; inflag=%d\n", a, b, aa, ba, inflag);*/
      /* Computations of key variables. */
      a1 = (a + n - 1) % n;
      b1 = (b + m - 1) % m;

      SubVec( P[a], P[a1], A );
      SubVec( Q[b], Q[b1], B );

      cross = AreaSign( Origin, A, B );
      aHB   = AreaSign( Q[b1], Q[b], P[a] );
      bHA   = AreaSign( P[a1], P[a], Q[b] );
      printf("%%cross=%d, aHB=%d, bHA=%d\n", cross, aHB, bHA );

      /* If A & B intersect, update inflag. */
      code = SegSegInt( P[a1], P[a], Q[b1], Q[b], p, q );
      printf("%%SegSegInt: code = %c\n", code );
      if ( code == '1' || code == 'v' ) {
         if ( inflag == Unknown && FirstPoint ) {
            aa = ba = 0;
            FirstPoint = FALSE;
            p0[X] = p[X]; p0[Y] = p[Y];
            printf("%8.2lf %8.2lf moveto\n", p0[X], p0[Y] );
         }
         inflag = InOut( p, inflag, aHB, bHA );
         printf("%%InOut sets inflag=%d\n", inflag);
      }

      /*-----Advance rules-----*/

      /* Special case: A & B overlap and oppositely oriented. */
      if ( ( code == 'e' ) && (Dot( A, B ) < 0) )
            PrintSharedSeg( p, q ), exit(EXIT_SUCCESS);

      /* Special case: A & B parallel and separated. */
      if ( (cross == 0) && ( aHB < 0) && ( bHA < 0 ) )
            printf("%%P and Q are disjoint.\n"), exit(EXIT_SUCCESS);

      /* Special case: A & B collinear. */
      else if ( (cross == 0) && ( aHB == 0) && ( bHA == 0 ) ) {
            /* Advance but do not output point. */
            if ( inflag == Pin )
               b = Advance( b, &ba, m, inflag == Qin, Q[b] );
            else
               a = Advance( a, &aa, n, inflag == Pin, P[a] );
         }

      /* Generic cases. */
      else if ( cross >= 0 ) {
         if ( bHA > 0)
            a = Advance( a, &aa, n, inflag == Pin, P[a] );
         else
            b = Advance( b, &ba, m, inflag == Qin, Q[b] );
      }
      else /* if ( cross < 0 ) */{
         if ( aHB > 0)
            b = Advance( b, &ba, m, inflag == Qin, Q[b] );
         else
            a = Advance( a, &aa, n, inflag == Pin, P[a] );
      }
      printf("%%After advances:a=%d, b=%d; aa=%d, ba=%d; inflag=%d\n", a, b, aa, ba, inflag);

   /* Quit when both adv. indices have cycled, or one has cycled twice. */
   } while ( ((aa < n) || (ba < m)) && (aa < 2*n) && (ba < 2*m) );

   if ( !FirstPoint ) /* If at least one point output, close up. */
            printf("%8.2lf %8.2lf lineto\n", p0[X], p0[Y] );

   /* Deal with special cases: not implemented. */
   if ( inflag == Unknown) 
      printf("%%The boundaries of P and Q do not cross.\n");
}
예제 #3
0
파일: chull.c 프로젝트: sleitner/cart
/*---------------------------------------------------------------------
Print: Prints out the vertices and the faces.  Uses the vnum indices 
corresponding to the order in which the vertices were input.
Output is in PostScript format.
---------------------------------------------------------------------*/
void	Print( void )
{
   /* Pointers to vertices, edges, faces. */
   tVertex  v;
   tEdge    e;
   tFace    f;
   int xmin, ymin, xmax, ymax;
   int a[3], b[3];  /* used to compute normal vector */
   /* Counters for Euler's formula. */
   int 	V = 0, E = 0 , F = 0;
   /* Note: lowercase==pointer, uppercase==counter. */

   /*-- find X min & max --*/
   v = vertices;
   xmin = xmax = v->v[X];
   do {
      if( v->v[X] > xmax ) xmax = v->v[X];
      else
	 if( v->v[X] < xmin ) xmin = v->v[X];
      v = v->next;
   } while ( v != vertices );
	
   /*-- find Y min & max --*/
   v = vertices;
   ymin = ymax = v->v[Y];
   do {
      if( v->v[Y] > ymax ) ymax = v->v[Y];
      else
	 if( v->v[Y] < ymin ) ymin = v->v[Y];
      v = v->next;
   } while ( v != vertices );
	
   /* PostScript header */
   printf("%%!PS\n");
   printf("%%%%BoundingBox: %d %d %d %d\n", 
	  xmin, ymin, xmax, ymax);
   printf(".00 .00 setlinewidth\n");
   printf("%d %d translate\n", -xmin+72, -ymin+72 );
   /* The +72 shifts the figure one inch from the lower left corner */

   /* Vertices. */
   v = vertices;
   do {                                 
      if( v->mark ) V++;           
      v = v->next;
   } while ( v != vertices );
   printf("\n%%%% Vertices:\tV = %d\n", V);
   printf("%%%% index:\tx\ty\tz\n");
   do {                                 
      printf( "%%%% %5d:\t%d\t%d\t%d\n", 
	     v->vnum, v->v[X], v->v[Y], v->v[Z] );
      v = v->next;
   } while ( v != vertices );
	
   /* Faces. */
   /* visible faces are printed as PS output */
   f = faces;
   do {
      ++F;                              
      f  = f ->next;
   } while ( f  != faces );
   printf("\n%%%% Faces:\tF = %d\n", F );
   printf("%%%% Visible faces only: \n");
   do {           
      /* Print face only if it is visible: if normal vector >= 0 */
      SubVec( f->vertex[1]->v, f->vertex[0]->v, a );
      SubVec( f->vertex[2]->v, f->vertex[1]->v, b );	  
      if(( a[0] * b[1] - a[1] * b[0] ) >= 0 )
      {
	 printf("%%%% vnums:  %d  %d  %d\n", 
		f->vertex[0]->vnum, 
		f->vertex[1]->vnum, 
		f->vertex[2]->vnum);
	 printf("newpath\n");
	 printf("%d\t%d\tmoveto\n", 
		f->vertex[0]->v[X], f->vertex[0]->v[Y] );
	 printf("%d\t%d\tlineto\n", 
		f->vertex[1]->v[X], f->vertex[1]->v[Y] );
	 printf("%d\t%d\tlineto\n", 
		f->vertex[2]->v[X], f->vertex[2]->v[Y] );
	 printf("closepath stroke\n\n");
      }
      f = f->next;
   } while ( f != faces );

   /* prints a list of all faces */
   printf("%%%% List of all faces: \n");
   printf("%%%%\tv0\tv1\tv2\t(vertex indices)\n");
   do {
      printf("%%%%\t%d\t%d\t%d\n",
	     f->vertex[0]->vnum,
	     f->vertex[1]->vnum,
	     f->vertex[2]->vnum );
      f = f->next;
   } while ( f != faces );
	
   /* Edges. */	
   e = edges;
   do {
      E++;
      e = e->next;
   } while ( e != edges );
   printf("\n%%%% Edges:\tE = %d\n", E );
   /* Edges not printed out (but easily added). */

   printf("\nshowpage\n\n");

   check = TRUE;
   CheckEuler( V, E, F );

}