Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

quad.c

Go to the documentation of this file.
00001 /*
00002 ** ----------------------------------------------------------------
00003 ** quad.c  -  Quadrilateral primitive module.
00004 **
00005 ** ----------------------------------------------------------------
00006 */
00007 
00038 /*
00039 ** ---------------------------------------------------------------
00040 ** Global variables and symbols:
00041 */
00042 #ifdef _WIN32
00043 #include <windows.h>
00044 #endif
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <math.h>
00048 #include <GL/gl.h>
00049 #include <GL/glu.h>
00050 
00051 #include "prm.h"
00052 #include "quad.h"
00053 #include "cd.h"
00054 #include "wd.h"
00055 #include "dsp.h"
00056 
00057 /*
00058 ** ---------------------------------------------------------------
00059 ** Local variables and symbols:
00060 */
00061 
00064 struct _quad {
00066   Coord         p[4];
00067  };
00068 
00069 
00070 /*
00071 ** ---------------------------------------------------------------
00072 ** Private functions:
00073 */
00074 static void quadPickCode( double x, double y, double xmin, double xmax,
00075                           double ymin, double ymax, int cod[4] );
00076 static int quadPickLine( double x, double y, double pick_tol,
00077                          double x0, double y0, double x1, double y1 );
00078 static void quadFaceNormal( Pnt3d *p0, Pnt3d *p1, Pnt3d *p2, Pnt3d *p3,
00079                             Vec3d *normal );
00080 static void quadBuildSolidPrm( Quad *quad, double height, Pnt3d *solid_prm );
00081 
00082 /*=========================  quadPickCode  =======================*/
00083 
00096 static void quadPickCode( double x, double y, double xmin, double xmax,
00097                           double ymin, double ymax, int cod[4] )
00098 {
00099  cod[0] = x < xmin;
00100  cod[1] = x > xmax;
00101  cod[2] = y < ymin;
00102  cod[3] = y > ymax;
00103 }
00104 
00105 /*=========================  quadPickLine  =======================*/
00106   
00126 static int quadPickLine( double x, double y, double pick_tol,
00127                          double x0, double y0, double x1, double y1 )
00128 {
00129  int    cod0[4], cod1[4];       /* pick code vectors of line points */
00130  double xmin, xmax, ymin, ymax; /* tolerance window for checking proximity  */
00131  int    j;
00132 
00133  xmin = x - pick_tol;
00134  xmax = x + pick_tol;
00135  ymin = y - pick_tol;
00136  ymax = y + pick_tol;
00137 
00138  quadPickCode( x1, y1, xmin, xmax, ymin, ymax, cod1 );
00139  do
00140  {
00141   quadPickCode( x0, y0, xmin, xmax, ymin, ymax, cod0 );
00142   for( j = 0; j < 4; j++ )
00143   {
00144    if( cod0[j] && cod1[j] )     /* test no-trivial pick */
00145     break;
00146   }
00147   if( j != 4 )
00148    break;
00149 
00150 /* move line point 0 to window limit 
00151  */
00152   if( cod0[0] )
00153   {
00154    y0 += (xmin - x0) * (y1 - y0) / (x1 - x0);
00155    x0 = xmin;
00156   }
00157   else if( cod0[1] )
00158   {
00159    y0 += (xmax - x0) * (y1 - y0) / (x1 - x0);
00160    x0 = xmax;
00161   }
00162   else if( cod0[2] )
00163   {
00164    x0 += (ymin - y0 ) * (x1 - x0) / (y1 - y0);
00165    y0 = ymin;
00166   }
00167   else if( cod0[3] )
00168   {
00169    x0 += (ymax - y0) * (x1 - x0) / (y1 - y0);
00170    y0 = ymax;
00171   }
00172   else
00173   {
00174    return( 1 );
00175   }
00176  } while( 1 );
00177 
00178  return( 0 );
00179 }
00180 
00181 /*=======================  quadFaceNormal  =======================*/
00182 
00193 static void quadFaceNormal( Pnt3d *p0, Pnt3d *p1, Pnt3d *p2, Pnt3d *p3,
00194                             Vec3d *normal )
00195 {
00196  double len;
00197 
00198  normal->x = 0.0;
00199  normal->y = 0.0;
00200  normal->z = 0.0;
00201 
00202  normal->x +=  (p1->y - p0->y) * (p2->z - p0->z) -
00203                (p1->z - p0->z) * (p2->y - p0->y);
00204  normal->y += -(p1->x - p0->x) * (p2->z - p0->z) +
00205                (p1->z - p0->z) * (p2->x - p0->x);
00206  normal->z +=  (p1->x - p0->x) * (p2->y - p0->y) -
00207                (p1->y - p0->y) * (p2->x - p0->x);
00208 
00209  normal->x +=  (p2->y - p0->y) * (p3->z - p0->z) -
00210                (p2->z - p0->z) * (p3->y - p0->y);
00211  normal->y += -(p2->x - p0->x) * (p3->z - p0->z) +
00212                (p2->z - p0->z) * (p3->x - p0->x);
00213  normal->z +=  (p2->x - p0->x) * (p3->y - p0->y) -
00214                (p2->y - p0->y) * (p3->x - p0->x);
00215 
00216  len = sqrt( normal->x*normal->x + normal->y*normal->y + normal->z*normal->z );
00217 
00218  if( len != 0.0 )
00219  {
00220   normal->x /= len;
00221   normal->y /= len;
00222   normal->z /= len;
00223  }
00224 }
00225 
00226 /*======================  quadBuildSolidPrm  ======================*/
00227 
00240 static void quadBuildSolidPrm( Quad *quad, double height, Pnt3d *solid_prm )
00241 {
00242  Pnt3d face[4];
00243  Vec3d prm_norm;
00244 
00245 /* Build a temporary face with the primitive points.
00246  */
00247  face[0].x = quad->p[0].x;
00248  face[0].y = quad->p[0].y;
00249  face[0].z = 0.0;
00250  face[1].x = quad->p[1].x;
00251  face[1].y = quad->p[1].y;
00252  face[1].z = 0.0;
00253  face[2].x = quad->p[2].x;
00254  face[2].y = quad->p[2].y;
00255  face[2].z = 0.0;
00256  face[3].x = quad->p[3].x;
00257  face[3].y = quad->p[3].y;
00258  face[3].z = 0.0;
00259 
00260 /* Compute the normal vector of the 2D primitive to find out whether
00261  * it has a clockwise or counter-clockwise orientation.
00262  * A negative z component of the normal vector indicates a 
00263  * clockwise orientation.
00264  */
00265  quadFaceNormal( &face[0], &face[1], &face[2], &face[3], &prm_norm );
00266 
00267 /* Build solid version of primitive with the base faces with normal
00268  * vectors pointing outward when traversing the vertices in 
00269  * counter-clockwise orientation. 
00270  */
00271  if( prm_norm.z < 0.0 )
00272  {
00273   solid_prm[0] = face[0];
00274   solid_prm[1] = face[1];
00275   solid_prm[2] = face[2];
00276   solid_prm[3] = face[3];
00277   
00278   solid_prm[4] = face[0];
00279   solid_prm[5] = face[3];
00280   solid_prm[6] = face[2];
00281   solid_prm[7] = face[1];
00282  }
00283  else
00284  {
00285   solid_prm[0] = face[0];
00286   solid_prm[1] = face[3];
00287   solid_prm[2] = face[2];
00288   solid_prm[3] = face[1];
00289 
00290   solid_prm[4] = face[0];
00291   solid_prm[5] = face[1];
00292   solid_prm[6] = face[2];
00293   solid_prm[7] = face[3];
00294  }
00295  solid_prm[4].z += height;
00296  solid_prm[5].z += height;
00297  solid_prm[6].z += height;
00298  solid_prm[7].z += height;
00299 }
00300 
00301 
00302 /*
00303 ** ---------------------------------------------------------------
00304 ** Public functions:
00305 */
00306 
00307 /*=========================  quadCreate  ========================*/
00308 
00309 Quad *quadCreate( void )
00310 {
00311  Quad *quad;
00312 
00313 /* Allocate memory for a new primitive.
00314  */
00315  quad = malloc( sizeof( Quad ) );
00316  if( quad == NULL )
00317   return( NULL );
00318 
00319 /* Set default values for new primitive.
00320  */
00321  quad->p[0].x = 0.0;
00322  quad->p[0].y = 0.0;
00323  quad->p[1].x = 1.0;
00324  quad->p[1].y = 1.0;
00325  quad->p[2].x = 1.0;
00326  quad->p[2].y = 0.0;
00327  quad->p[3].x = 0.0;
00328  quad->p[3].y = 1.0;
00329 
00330  return( quad );
00331 }
00332 
00333 /*=========================  quadDelete  ========================*/
00334 
00335 void quadDelete( Quad *quad )
00336 {
00337  free( quad );
00338 }
00339 
00340 /*==========================  quadRead  =========================*/
00341 
00342 void quadRead( Quad *quad, FILE *fd )
00343 {
00344 /*** COMPLETE HERE: 16 ***/
00345 }
00346 
00347 /*=========================  quadWrite  =========================*/
00348 
00349 void quadWrite( Quad *quad, FILE *fd )
00350 {
00351 /*** COMPLETE HERE: 17 ***/
00352 }
00353 
00354 /*========================  quadGetNPts  ========================*/
00355 
00356 int quadGetNPts( Quad *quad )
00357 {
00358  return( 4 );
00359 }
00360 
00361 /*=======================  quadSetCoords  =======================*/
00362 
00363 void quadSetCoords( Quad *quad, int id, double x, double y )
00364 {
00365 /*** COMPLETE HERE: 18 ***/
00366 }
00367 
00368 /*=======================  quadGetCoords  =======================*/
00369 
00370 void quadGetCoords( Quad *quad, int id, double *x, double *y )
00371 {
00372 /*** COMPLETE HERE: 19 ***/
00373 }
00374 
00375 /*=======================  quadSet1stPt  ========================*/
00376 
00377 void quadSet1stPt( Quad *quad, double x, double y )
00378 {
00379 /*** COMPLETE HERE: 20 ***/
00380 }
00381 
00382 /*=======================  quadSet2ndPt  ========================*/
00383 
00384 void quadSet2ndPt( Quad *quad, double x, double y )
00385 {
00386 /*** COMPLETE HERE: 21 ***/
00387 }
00388 
00389 /*=======================  quadPickArea  ========================*/
00390 
00391 int quadPickArea( Quad *quad, double x, double y )
00392 {
00393  int     ni = 0;            /* no. of intersections of ray with polygon */
00394  double  px0, py0;          /* coordinates of current edge first point */
00395  double  px1, py1;          /* coordinates of current edge second point */
00396  double  xc;                /* x coordinate of intersection point */
00397  int     i;
00398 
00399  for( i = 0; i < 4; i++ )
00400  {
00401   quadGetCoords( quad,       i, &px0, &py0 );
00402   quadGetCoords( quad, (i+1)%4, &px1, &py1 );
00403   if( !(py0 == py1) &&                /* disregard horizontal edges */
00404       !((py0 > y) && (py1 > y)) &&    /* disregard edges above point */
00405       !((py0 < y) && (py1 < y)) &&    /* disregard edges below point */
00406       !((px0 < x) && (px1 < x)) )     /* disregard edges to the left */
00407   {
00408    if( py0 == y )   /* first edge point at same level of given point */
00409    {
00410     if( (px0 > x) && (py1 > y) )
00411      ni++;           /* edge above and to the right of given point */
00412    }
00413    else
00414    {
00415     if( py1 == y )   /* second edge point at same level of given point */
00416     {
00417      if( (px1 > x) && (py0 > y) )
00418       ni++;          /* edge above and to the right of given point */
00419     }
00420     else     /* given point level is within edge end levels */
00421     {
00422      if( (px0 > x) && (px1 > x) )
00423       ni++;  /* edge is completely to the right of given point */
00424      else
00425      {       /* check to see whether intersection point is to the right */
00426       double dx = px0 - px1;
00427       xc = px0;
00428       if( dx != 0.0 )
00429         xc += ( y - py0 ) * dx / ( py0 - py1 );
00430       if( xc > x )
00431         ni++;
00432      }
00433     }
00434    }
00435   }
00436  }
00437 
00438  return( ni % 2 );
00439 }
00440 
00441 /*======================  quadPickVertex  =======================*/
00442 
00443 int quadPickVertex( Quad *quad, double x, double y, double tol,
00444                     int *id )
00445 {
00446 /*** COMPLETE HERE: 22 ***/
00447  
00448  return( 0 );
00449 }
00450 
00451 /*=======================  quadPickSide  ========================*/
00452 
00453 int quadPickSide( Quad *quad, double x, double y, double tol,
00454                   int *id )
00455 {
00456 /*** COMPLETE HERE: 23 ***/
00457 
00458  return( 0 );
00459 }
00460 
00461 /*=======================  quadTranslate  =======================*/
00462 
00463 void quadTranslate( Quad *quad, double dx, double dy )
00464 {
00465 /*** COMPLETE HERE: 24 ***/
00466 }
00467 
00468 /*====================  quadTranslateVertex  ====================*/
00469 
00470 void quadTranslateVertex( Quad *quad, int id, double dx, double dy )
00471 {
00472 /*** COMPLETE HERE: 25 ***/
00473 }
00474 
00475 /*=====================  quadTranslateSide  =====================*/
00476 
00477 void quadTranslateSide( Quad *quad, int id, double dx, double dy )
00478 {
00479 /*** COMPLETE HERE: 26 ***/
00480 }
00481 
00482 /*=========================  quadGetBox  ========================*/
00483 
00484 void quadGetBox( Quad *quad, double *xmin, double *xmax, 
00485                              double *ymin, double *ymax )
00486 {
00487 /*** COMPLETE HERE: 27 ***/
00488 }
00489 
00490 /*====================  quadDisplayBoundary  ====================*/
00491 
00492 void quadDisplayBoundary( Quad *quad )
00493 {
00494 /*** COMPLETE HERE: 28 ***/
00495 }
00496 
00497 /*====================  quadDisplayInterior  ====================*/
00498 
00499 void quadDisplayInterior( Quad *quad )
00500 {
00501 /*** COMPLETE HERE: 29 ***/
00502 }
00503 
00504 /*=====================  quadDisplaySolid  ======================*/
00505 
00506 void quadDisplaySolid( Quad *quad, double height )
00507 {
00508 /*** COMPLETE HERE: 29-A ***/
00509 /*** Study function quadDisplayZbuffer below ***/
00510 /*** Use OpenGL functions ***/
00511 }
00512 
00513 /*======================  quadHighltSolid  ======================*/
00514 
00515 void quadHighltSolid( Quad *quad, double height )
00516 {
00517 /*** COMPLETE HERE: 29-B ***/
00518 /*** Use OpenGL functions ***/
00519 }
00520 
00521 /*====================  quadDisplayZbuffer  =====================*/
00522 
00523 void quadDisplayZbuffer( Quad *quad, double height, long int color )
00524 {
00525  Pnt3d solid_prm[8];    /* solid version of primitive */
00526  Vec3d normal;          /* face normal vector */
00527  
00528 /* If the height of the primitive is null,
00529  * just display one face: the primitive.
00530  * To display means to project the face and send it to the zbuffer module.
00531  */
00532  if( height == 0.0 )
00533  {
00534   dspZbfBeginPoly( color, 0.0, 0.0, 1.0 );
00535   dspZbfVertex( quad->p[0].x, quad->p[0].y, 0.0 );
00536   dspZbfVertex( quad->p[1].x, quad->p[1].y, 0.0 );
00537   dspZbfVertex( quad->p[2].x, quad->p[2].y, 0.0 );
00538   dspZbfVertex( quad->p[3].x, quad->p[3].y, 0.0 );
00539   dspZbfEndPoly( );
00540   return;
00541  }
00542  
00543 /* Build solid version.
00544  */
00545  quadBuildSolidPrm( quad, height, solid_prm );
00546  
00547 /* Display base faces (send to zbuffer module).
00548  */
00549  dspZbfBeginPoly( color, 0.0, 0.0, -1.0 );
00550  dspZbfVertex( solid_prm[0].x, solid_prm[0].y, solid_prm[0].z );
00551  dspZbfVertex( solid_prm[1].x, solid_prm[1].y, solid_prm[1].z );
00552  dspZbfVertex( solid_prm[2].x, solid_prm[2].y, solid_prm[2].z );
00553  dspZbfVertex( solid_prm[3].x, solid_prm[3].y, solid_prm[3].z );
00554  dspZbfEndPoly( );
00555 
00556  dspZbfBeginPoly( color, 0.0, 0.0, 1.0 );
00557  dspZbfVertex( solid_prm[4].x, solid_prm[4].y, solid_prm[4].z );
00558  dspZbfVertex( solid_prm[5].x, solid_prm[5].y, solid_prm[5].z );
00559  dspZbfVertex( solid_prm[6].x, solid_prm[6].y, solid_prm[6].z );
00560  dspZbfVertex( solid_prm[7].x, solid_prm[7].y, solid_prm[7].z );
00561  dspZbfEndPoly( );
00562 
00563 /* Display lateral faces (send to zbuffer module).
00564  */
00565  quadFaceNormal( &solid_prm[0], &solid_prm[4], &solid_prm[7], &solid_prm[1],
00566                  &normal );
00567  dspZbfBeginPoly( color, normal.x, normal.y, normal.z );
00568  dspZbfVertex( solid_prm[0].x, solid_prm[0].y, solid_prm[0].z );
00569  dspZbfVertex( solid_prm[4].x, solid_prm[4].y, solid_prm[4].z );
00570  dspZbfVertex( solid_prm[7].x, solid_prm[7].y, solid_prm[7].z );
00571  dspZbfVertex( solid_prm[1].x, solid_prm[1].y, solid_prm[1].z );
00572  dspZbfEndPoly( );
00573 
00574  quadFaceNormal( &solid_prm[1], &solid_prm[7], &solid_prm[6], &solid_prm[2],
00575                  &normal );
00576  dspZbfBeginPoly( color, normal.x, normal.y, normal.z );
00577  dspZbfVertex( solid_prm[1].x, solid_prm[1].y, solid_prm[1].z );
00578  dspZbfVertex( solid_prm[7].x, solid_prm[7].y, solid_prm[7].z );
00579  dspZbfVertex( solid_prm[6].x, solid_prm[6].y, solid_prm[6].z );
00580  dspZbfVertex( solid_prm[2].x, solid_prm[2].y, solid_prm[2].z );
00581  dspZbfEndPoly( );
00582 
00583  quadFaceNormal( &solid_prm[2], &solid_prm[6], &solid_prm[5], &solid_prm[3],
00584                  &normal );
00585  dspZbfBeginPoly( color, normal.x, normal.y, normal.z );
00586  dspZbfVertex( solid_prm[2].x, solid_prm[2].y, solid_prm[2].z );
00587  dspZbfVertex( solid_prm[6].x, solid_prm[6].y, solid_prm[6].z );
00588  dspZbfVertex( solid_prm[5].x, solid_prm[5].y, solid_prm[5].z );
00589  dspZbfVertex( solid_prm[3].x, solid_prm[3].y, solid_prm[3].z );
00590  dspZbfEndPoly( );
00591 
00592  quadFaceNormal( &solid_prm[3], &solid_prm[5], &solid_prm[4], &solid_prm[0],
00593                  &normal );
00594  dspZbfBeginPoly( color, normal.x, normal.y, normal.z );
00595  dspZbfVertex( solid_prm[3].x, solid_prm[3].y, solid_prm[3].z );
00596  dspZbfVertex( solid_prm[5].x, solid_prm[5].y, solid_prm[5].z );
00597  dspZbfVertex( solid_prm[4].x, solid_prm[4].y, solid_prm[4].z );
00598  dspZbfVertex( solid_prm[0].x, solid_prm[0].y, solid_prm[0].z );
00599  dspZbfEndPoly( );
00600 }
00601 
00603  solid_prm[5].x, solid_prm[5].y, solid_prm[5].z );
00604  dspZbfVertex( solid_prm[3].x, solid_prm[3].y, solid_prm[3].z );
00605  dspZbfEndPoly( );
00606 
00607  quadFaceNormal( &solid_prm[3], &solid_prm[5], &solid_prm[4], &solid_prm[0],
00608                  &normal );
00609  dspZbfBeginPoly( color, normal.x, normal.y, normal.z );
00610  dspZbfVertex( solid_prm[3].x, solid_prm[3].y, solid_prm[3].z );
00611  dspZbfVertex( solid_prm[5].x, solid_prm[5].y, solid_prm[5].z );
00612  dspZbfVertex( solid_prm[4].x, solid_prm[4].y, solid_prm[4].z );
00613  dspZbfVertex( solid_prm[0].x, solid_prm[0].y, solid_prm[0].z );
00614  dspZbfEndPoly( );
00615 }
00616 

Generated on Tue Nov 8 10:58:00 2005 for Trab3 by doxygen1.2.18