Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

circ.cpp

Go to the documentation of this file.
00001 /*
00002 ** ----------------------------------------------------------------
00003 ** circ.cpp  -  Circle primitive class.
00004 **
00005 ** ----------------------------------------------------------------
00006 */
00007 
00034 /*
00035 ** ---------------------------------------------------------------
00036 ** Global variables and symbols:
00037 */
00038 #ifdef _WIN32
00039 #include <windows.h>
00040 #endif
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <math.h>
00044 #include <GL/gl.h>
00045 #include <GL/glu.h>
00046 
00047 #include "prm.h"
00048 #include "circ.h"
00049 #include "cd.h"
00050 #include "wd.h"
00051 #include "dsp.h"
00052 
00053 /*
00054 ** ---------------------------------------------------------------
00055 ** Initialization of class variables:
00056 */
00059 const int Circ::CIRC_SEGS = 32;
00060 
00063 const double Circ::M_PI = 3.141592654;
00064 
00065 /*
00066 ** ---------------------------------------------------------------
00067 ** Public constructor and destructor functions:
00068 **
00069 */
00070 /*==========================  Circ::Circ  =========================*/
00071 
00072 Circ::Circ( )
00073 {
00074 /* Set primitive type.
00075  */
00076  this->type = PRM_CIRC;
00077 
00078 /* Set default values for new primitive.
00079  */
00080  c.x = 0.0;
00081  c.y = 0.0;
00082  r = 1.0;
00083 }
00084 
00085 /*==========================  Circ::Circ  =========================*/
00086 
00087 Circ::Circ(int back) : Prm( back )
00088 {
00089 /* Set primitive type.
00090  */
00091  this->type = PRM_CIRC;
00092 
00093 /* Set default values for new primitive.
00094  */
00095  c.x = 0.0;
00096  c.y = 0.0;
00097  r = 1.0;
00098 }
00099 
00100 /*==========================  Circ::~Circ  ========================*/
00101 
00102 Circ::~Circ( )
00103 {
00104 }
00105 
00106 /*
00107 ** ---------------------------------------------------------------
00108 ** Protected instance (object) functions
00109 **
00110 */
00111 /*====================  Circ::GetLateralNormal  ===================*/
00112 
00113 void Circ::GetLateralNormal( Coord* p, Coord* normal )
00114 {
00115  double len; 
00116  normal->x = p->x - c.x;
00117  normal->y = p->y - c.y;
00118  len = sqrt( normal->x*normal->x + normal->y*normal->y );
00119  normal->x /= len;
00120  normal->y /= len;
00121 }
00122 
00123 /*
00124 ** ---------------------------------------------------------------
00125 ** Public instance (object) functions
00126 ** (implemented in the derived class):
00127 **
00128 */
00129 /*==========================  Circ::Read  =========================*/
00130 
00131 void Circ::Read( FILE* fd )
00132 {
00133  fscanf( fd, "%lg %lg %lg", &c.x, &c.y, &r );
00134 }
00135 
00136 /*=========================  Circ::Write  =========================*/
00137 
00138 void Circ::Write( FILE* fd )
00139 {
00140  fprintf( fd, "%g %g %g\n", c.x, c.y, r );
00141 }
00142 
00143 /*========================  Circ::GetNPts  ========================*/
00144 
00145 int Circ::GetNPts( )
00146 {
00147  return( 4 );
00148 }
00149 
00150 /*=======================  Circ::SetCoords  =======================*/
00151 
00152 void Circ::SetCoords( int id, double x, double y )
00153 {
00154  r = sqrt( (x - c.x) * (x - c.x) + (y - c.y) * (y - c.y) );
00155 }
00156 
00157 /*=======================  Circ::GetCoords  =======================*/
00158 
00159 void Circ::GetCoords( int id, double* x, double* y )
00160 {
00161  *x = c.x + r;
00162  *y = c.y;
00163 }
00164 
00165 /*=======================  Circ::Set1stPt  ========================*/
00166 
00167 void Circ::Set1stPt( double x, double y )
00168 {
00169  c.x = x;
00170  c.y = y;
00171 }
00172 
00173 /*=======================  Circ::Set2ndPt  ========================*/
00174 
00175 void Circ::Set2ndPt( double x, double y )
00176 {
00177  r = sqrt( (x - c.x) * (x - c.x) + (y - c.y) * (y - c.y) );
00178 }
00179 
00180 /*=======================  Circ::PickArea  ========================*/
00181 
00182 int Circ::PickArea( double x, double y )
00183 {
00184  double dist;         /* distance from point to center */
00185 
00186  dist = sqrt( (x - c.x) * (x - c.x) + 
00187               (y - c.y) * (y - c.y) );
00188 
00189  if( dist <= r )
00190  {
00191   return( 1 );
00192  }
00193 
00194  return( 0 );
00195 }
00196 
00197 /*======================  Circ::PickVertex  =======================*/
00198 
00199 int Circ::PickVertex( double x, double y, double tol, int* id )
00200 {
00201  if(      (ABS( (c.x + r) - x ) <= tol ) && 
00202           (ABS(  c.y      - y ) <= tol ) )
00203  {
00204   *id = 0;
00205   return( 1 );
00206  }
00207  else if( (ABS(  c.x      - x ) <= tol ) && 
00208           (ABS( (c.y + r) - y ) <= tol ) )
00209  {
00210   *id = 1;
00211   return( 1 );
00212  }
00213  else if( (ABS( (c.x - r) - x ) <= tol ) && 
00214           (ABS(  c.y      - y ) <= tol ) )
00215  {
00216   *id = 2;
00217   return( 1 );
00218  }
00219  else if( (ABS(  c.x      - x ) <= tol ) && 
00220           (ABS( (c.y - r) - y ) <= tol ) )
00221  {
00222   *id = 3;
00223   return( 1 );
00224  }
00225 
00226  return( 0 );
00227 }
00228 
00229 /*=======================  Circ::PickSide  ========================*/
00230 
00231 int Circ::PickSide( double x, double y, double tol, int* id )
00232 {
00233  return( 0 );
00234 }
00235 
00236 /*=======================  Circ::Translate  =======================*/
00237 
00238 void Circ::Translate( double dx, double dy )
00239 {
00240  c.x += dx;
00241  c.y += dy;
00242 }
00243 
00244 /*====================  Circ::TranslateVertex  ====================*/
00245 
00246 void Circ::TranslateVertex( int id, double dx, double dy )
00247 {
00248  double x;
00249  double y;
00250 
00251  if( id == 0 )
00252  {
00253   x = c.x + r + dx;
00254   y = c.y;
00255   if( x < (c.x + COORD_TOL) )
00256    return;
00257  }
00258  else if( id == 1 )
00259  {
00260   x = c.x;
00261   y = c.y + r + dy;
00262   if( y < (c.y + COORD_TOL) )
00263    return;
00264  }
00265  else if( id == 2 )
00266  {
00267   x = c.x - r + dx;
00268   y = c.y;
00269   if( x > (c.x - COORD_TOL) )
00270    return;
00271  }
00272  else if( id == 3 )
00273  {
00274   x = c.x;
00275   y = c.y - r + dy;
00276   if( y > (c.y - COORD_TOL) )
00277    return;
00278  }
00279  else
00280  {
00281   return;
00282  }
00283 
00284  r = sqrt( (x - c.x) * (x - c.x) + (y - c.y) * (y - c.y) );
00285 }
00286 
00287 /*=====================  Circ::TranslateSide  =====================*/
00288 
00289 void Circ::TranslateSide( int id, double dx, double dy )
00290 {
00291 }
00292 
00293 /*=========================  Circ::GetBox  ========================*/
00294 
00295 void Circ::GetBox( double* xmin, double* xmax, double* ymin, double* ymax )
00296 {
00297  *xmin = c.x - r;
00298  *xmax = c.x + r;
00299  *ymin = c.y - r;
00300  *ymax = c.y + r;
00301 }
00302 
00303 /*====================  Circ::DisplayBoundary  ====================*/
00304 
00305 void Circ::DisplayBoundary( )
00306 {
00307  double d = 2.0 * r;
00308 
00309  wdArc( c.x, c.y, d, d, 0.0, 360.0 ); 
00310  wdMark( c.x + r, c.y ); 
00311  wdMark( c.x, c.y + r ); 
00312  wdMark( c.x - r, c.y ); 
00313  wdMark( c.x, c.y - r ); 
00314 }
00315 
00316 /*====================  Circ::DisplayInterior  ====================*/
00317 
00318 void Circ::DisplayInterior( )
00319 {
00320  double d = 2.0 * r;
00321 
00322  wdSector( c.x, c.y, d, d, 0.0, 360.0 ); 
00323 }
00324 
00325 /*=====================  Circ::DisplaySolid  ======================*/
00326 
00327 void Circ::DisplaySolid( )
00328 {
00329  Coord p[32];                     /* circle points */
00330  Coord normal;                    /* face normal vector */
00331  double alpha;                    /* circle angle */
00332  double delta = 2*M_PI/CIRC_SEGS; /* increment of circle angle */
00333  int i;
00334 
00335 /* Build circle points.
00336  */
00337  alpha = 0.0;
00338  for( i = 0; i < CIRC_SEGS; i++ )
00339  {
00340   p[i].x = c.x + r * cos( alpha );
00341   p[i].y = c.y + r * sin( alpha );
00342   alpha += delta;
00343  }
00344 
00345 /* Display base circle.
00346  */
00347  glBegin( GL_TRIANGLE_FAN );
00348  glNormal3d( 0.0, 0.0, -1.0 );
00349  for( i = 0; i <= CIRC_SEGS; i++ )
00350  {
00351   glVertex3d( p[i%CIRC_SEGS].x, p[i%CIRC_SEGS].y, 0.0 );
00352  }
00353  glEnd( );
00354 
00355 /* If the height of the primitive is null, return;
00356  */
00357  if( height == 0.0 )
00358  {
00359   return;
00360  }
00361 
00362 /* Display top circle.
00363  */
00364  glBegin( GL_TRIANGLE_FAN );
00365  glNormal3d( 0.0, 0.0,  1.0 );
00366  for( i = 0; i <= CIRC_SEGS; i++ )
00367  {
00368   glVertex3d( p[i%CIRC_SEGS].x, p[i%CIRC_SEGS].y, height );
00369  }
00370  glEnd( );
00371 
00372 /* Display lateral faces.
00373  */
00374  glBegin( GL_QUADS );
00375  for( i = 0; i < CIRC_SEGS; i++ )
00376  {
00377   GetLateralNormal( &p[i], &normal );
00378   glNormal3d( normal.x, normal.y, 0.0 );
00379   glVertex3d( p[i].x, p[i].y, height );
00380   glVertex3d( p[i].x, p[i].y, 0.0 );
00381   GetLateralNormal( &p[(i+1)%CIRC_SEGS], &normal );
00382   glNormal3d( normal.x, normal.y, 0.0 );
00383   glVertex3d( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, 0.0 );
00384   glVertex3d( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, height );
00385  }
00386  glEnd( );
00387 }
00388 
00389 /*======================  Circ::HighltSolid  ======================*/
00390   
00391 void Circ::HighltSolid( )
00392 {
00393  Coord p[32];                     /* circle points */
00394  double alpha;                    /* circle angle */
00395  double delta = 2*M_PI/CIRC_SEGS; /* increment of circle angle */
00396  int i;
00397  
00398 /* Build circle points.
00399  */
00400  alpha = 0.0;
00401  for( i = 0; i < CIRC_SEGS; i++ )
00402  {
00403   p[i].x = c.x + r * cos( alpha );
00404   p[i].y = c.y + r * sin( alpha );
00405   alpha += delta;
00406  }
00407 
00408 /* Display base circle.
00409  */
00410  glBegin( GL_LINE_LOOP );
00411  for( i = 0; i < CIRC_SEGS; i++ )
00412  {
00413   glVertex3d( p[i].x, p[i].y, 0.0 );
00414  }
00415  glEnd( );
00416 
00417  glBegin( GL_POINTS );
00418  for( i = 0; i < CIRC_SEGS; i++ )
00419  {
00420   glVertex3d( p[i].x, p[i].y, 0.0 );
00421  }
00422  glEnd( );
00423 
00424 /* If the height of the primitive is null, return;
00425  */
00426  if( height == 0.0 )
00427  {
00428   return;
00429  }
00430 
00431 /* Display top circle.
00432  */
00433  glBegin( GL_LINE_LOOP );
00434  for( i = 0; i < CIRC_SEGS; i++ )
00435  {
00436   glVertex3d( p[i].x, p[i].y, height );
00437  }
00438  glEnd( );
00439 
00440  glBegin( GL_POINTS );
00441  for( i = 0; i < CIRC_SEGS; i++ )
00442  {
00443   glVertex3d( p[i].x, p[i].y, height );
00444  }
00445  glEnd( );
00446 
00447 /* Display lateral edges.
00448  */
00449  glBegin( GL_LINES );
00450  for( i = 0; i < CIRC_SEGS; i++ )
00451  {
00452   glVertex3d( p[i].x, p[i].y, height );
00453   glVertex3d( p[i].x, p[i].y, 0.0 );
00454  }
00455  glEnd( );
00456 }
00457 
00458 /*====================  Circ::DisplayZbuffer  =====================*/
00459 
00460 void Circ::DisplayZbuffer( )
00461 {
00462  Coord p[32];                     /* circle points */
00463  Coord normal;                    /* face normal vector */
00464  double alpha;                    /* circle angle */
00465  double delta = 2*M_PI/CIRC_SEGS; /* increment of circle angle */
00466  Coord  midpt;                    /* auxiliar lateral face mid point */
00467  int i;
00468 
00469 /* Build circle points.
00470  */
00471  alpha = 0.0;
00472  for( i = 0; i < CIRC_SEGS; i++ )
00473  {
00474   p[i].x = c.x + r * cos( alpha );
00475   p[i].y = c.y + r * sin( alpha );
00476   alpha += delta;
00477  }
00478 
00479 /* Display base circle.
00480  * To display means to project the face and send it to the zbuffer module.
00481  */
00482  for( i = 0; i < CIRC_SEGS; i++ )
00483  {
00484   Dsp::ZbfBeginPoly( color, 0.0, 0.0, -1.0 );
00485   Dsp::ZbfVertex( c.x, c.y, 0.0 );
00486   Dsp::ZbfVertex( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, 0.0 );
00487   Dsp::ZbfVertex( p[i].x, p[i].y, 0.0 );
00488   Dsp::ZbfEndPoly( );
00489  }
00490 
00491 /* If the height of the primitive is null, return;
00492  */
00493  if( height == 0.0 )
00494  {
00495   return;
00496  }
00497 
00498 /* Display top circle (send to zbuffer module).
00499  */
00500  for( i = 0; i < CIRC_SEGS; i++ )
00501  {
00502   Dsp::ZbfBeginPoly( color, 0.0, 0.0, 1.0 );
00503   Dsp::ZbfVertex( c.x, c.y, height );
00504   Dsp::ZbfVertex( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, height );
00505   Dsp::ZbfVertex( p[i].x, p[i].y, height );
00506   Dsp::ZbfEndPoly( );
00507  }
00508 
00509 /* Display lateral faces (send to zbuffer module).
00510  */
00511  for( i = 0; i < CIRC_SEGS; i++ )
00512  {
00513   midpt.x = (p[i].x + p[(i+1)%CIRC_SEGS].x) * 0.5;
00514   midpt.y = (p[i].y + p[(i+1)%CIRC_SEGS].y) * 0.5;
00515   GetLateralNormal( &midpt, &normal );
00516   Dsp::ZbfBeginPoly( color, normal.x, normal.y, 0.0 );
00517   Dsp::ZbfVertex( p[i].x, p[i].y, height );
00518   Dsp::ZbfVertex( p[i].x, p[i].y, 0.0 );
00519   Dsp::ZbfVertex( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, 0.0 );
00520   Dsp::ZbfVertex( p[(i+1)%CIRC_SEGS].x, p[(i+1)%CIRC_SEGS].y, height );
00521   Dsp::ZbfEndPoly( );
00522  }
00523 }
00524 

Generated on Mon Jun 21 12:45:12 2010 for Trab4 by  doxygen 1.4.2-20050421