00001
00002
00003
00004
00005
00006
00007
00034
00035
00036
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
00056
00059 const int Circ::CIRC_SEGS = 32;
00060
00063 const double Circ::M_PI = 3.141592654;
00064
00065
00066
00067
00068
00069
00070
00071
00072 Circ::Circ( )
00073 {
00074
00075
00076 this->type = PRM_CIRC;
00077
00078
00079
00080 c.x = 0.0;
00081 c.y = 0.0;
00082 r = 1.0;
00083 }
00084
00085
00086
00087 Circ::Circ(int back) : Prm( back )
00088 {
00089
00090
00091 this->type = PRM_CIRC;
00092
00093
00094
00095 c.x = 0.0;
00096 c.y = 0.0;
00097 r = 1.0;
00098 }
00099
00100
00101
00102 Circ::~Circ( )
00103 {
00104 }
00105
00106
00107
00108
00109
00110
00111
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
00126
00127
00128
00129
00130
00131 void Circ::Read( FILE* fd )
00132 {
00133 fscanf( fd, "%lg %lg %lg", &c.x, &c.y, &r );
00134 }
00135
00136
00137
00138 void Circ::Write( FILE* fd )
00139 {
00140 fprintf( fd, "%g %g %g\n", c.x, c.y, r );
00141 }
00142
00143
00144
00145 int Circ::GetNPts( )
00146 {
00147 return( 4 );
00148 }
00149
00150
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
00158
00159 void Circ::GetCoords( int id, double* x, double* y )
00160 {
00161 *x = c.x + r;
00162 *y = c.y;
00163 }
00164
00165
00166
00167 void Circ::Set1stPt( double x, double y )
00168 {
00169 c.x = x;
00170 c.y = y;
00171 }
00172
00173
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
00181
00182 int Circ::PickArea( double x, double y )
00183 {
00184 double dist;
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
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
00230
00231 int Circ::PickSide( double x, double y, double tol, int* id )
00232 {
00233 return( 0 );
00234 }
00235
00236
00237
00238 void Circ::Translate( double dx, double dy )
00239 {
00240 c.x += dx;
00241 c.y += dy;
00242 }
00243
00244
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
00288
00289 void Circ::TranslateSide( int id, double dx, double dy )
00290 {
00291 }
00292
00293
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
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
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
00326
00327 void Circ::DisplaySolid( )
00328 {
00329 Coord p[32];
00330 Coord normal;
00331 double alpha;
00332 double delta = 2*M_PI/CIRC_SEGS;
00333 int i;
00334
00335
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
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
00356
00357 if( height == 0.0 )
00358 {
00359 return;
00360 }
00361
00362
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
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
00390
00391 void Circ::HighltSolid( )
00392 {
00393 Coord p[32];
00394 double alpha;
00395 double delta = 2*M_PI/CIRC_SEGS;
00396 int i;
00397
00398
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
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
00425
00426 if( height == 0.0 )
00427 {
00428 return;
00429 }
00430
00431
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
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
00459
00460 void Circ::DisplayZbuffer( )
00461 {
00462 Coord p[32];
00463 Coord normal;
00464 double alpha;
00465 double delta = 2*M_PI/CIRC_SEGS;
00466 Coord midpt;
00467 int i;
00468
00469
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
00480
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
00492
00493 if( height == 0.0 )
00494 {
00495 return;
00496 }
00497
00498
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
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