00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "jed_defs.h"
00025
00026 #ifndef __GEOMETRIA__
00027 #error "No incluya a cilindro.h, incluya a geometria.h!"
00028 #endif
00029
00030 #ifdef VEL_ROSITA
00031 #include "toolkits/geom/geometria.h"
00032 #endif
00033
00034 class CILINDRO : public PRIMITIVA_GEOMETRICA
00035 {
00036 private:
00037 double _radio1;
00038 double _radio2;
00039 double _altura;
00040 #ifdef GL_ENABLED
00041 int paralelos;
00042 int meridianos;
00043 GLUquadricObj *Textura_glu;
00044 #endif
00045 IMAGEN *imagen;
00046
00047 double interseccion_cono(const RAYO *in_Rayo, const double in_r,
00048 const double in_h,
00049 VECTOR &out_punto, VECTOR &out_normal);
00050
00051 double interseccion_cilindro(const RAYO *in_Rayo, const double in_r,
00052 const double in_h,
00053 VECTOR &out_punto, VECTOR &out_normal);
00054
00055 double interseccion_tapa(RAYO *in_Rayo, const double in_r,
00056 const double in_h,
00057 VECTOR &out_punto, VECTOR &out_normal);
00058
00059 public:
00060 CILINDRO(double r1, double r2, double h);
00061 virtual ~CILINDRO();
00062
00063
00064 double interseccion(RAYO *Rayo, VECTOR &punto, VECTOR &normal);
00065
00066
00067 void valores(double *r1, double *r2, double *h);
00068 void set_valores(double r1, double r2, double h);
00069 void anexar_textura(IMAGEN *img);
00070 int clasificar_punto(VECTOR p);
00071 virtual GEOMETRIA *crear_copia(void);
00072
00073 void minmax(VECTOR *min, VECTOR *max);
00074
00075 #ifdef GL_ENABLED
00076 void
00077 pintar_gl(CALIDAD_VISUAL *Calidad, MATERIAL* Material, CAMARA *Camara);
00078 #endif
00079 void pintar_povray(FILE *fd);
00080 void pintar_aqz(FILE *fd);
00081 };
00082
00083
00084
00085
00086
00087 inline double
00088 CILINDRO::interseccion_tapa(RAYO *in_Rayo, const double in_r,
00089 const double in_h,
00090 VECTOR &out_punto, VECTOR &out_normal)
00108 {
00109 double t;
00110 VECTOR p;
00111 VECTOR proy;
00112 VECTOR o(0, 0, 0);
00113
00114 if ( fabs(in_Rayo->direccion.z) > EPSILON ) {
00115
00116 t = (in_h-in_Rayo->origen.z)/in_Rayo->direccion.z;
00117 if ( t > -EPSILON ) {
00118 p = in_Rayo->origen + in_Rayo->direccion * t;
00119 proy.x = p.x;
00120 proy.y = p.y;
00121 proy.z = 0;
00122 if ( DISTANCIA_V(proy, o) < in_r ) {
00123 out_normal.x = out_normal.y = 0;
00124 out_normal.z = 1;
00125 out_punto = p;
00126 return t;
00127 }
00128 }
00129 }
00130
00131 return 0.0;
00132 }
00133
00134 inline double
00135 CILINDRO::interseccion_cono(const RAYO *in_Rayo, const double in_r,
00136 const double in_h,
00137 VECTOR &out_punto, VECTOR &out_normal)
00184 {
00185 double A, B, C, discriminante, t0 ;
00186
00187
00188 RAYO r = (*in_Rayo);
00189 r.origen.z -= in_h/2;
00190 r.direccion.normalizar();
00191
00192
00193 A = SQUARE(r.direccion.x) +
00194 SQUARE(r.direccion.y) -
00195 SQUARE(r.direccion.z * in_r / in_h);
00196
00197
00198 B = 2 *
00199 ((r.direccion.x * r.origen.x) +
00200 (r.direccion.y * r.origen.y) -
00201 (r.direccion.z * r.origen.z * SQUARE(in_r)) /
00202 SQUARE(in_h)
00203 );
00204
00205
00206 C = SQUARE(r.origen.x) +
00207 SQUARE(r.origen.y) -
00208 SQUARE(r.origen.z * in_r / in_h);
00209
00210
00211
00212 discriminante = SQUARE(B) - 4*A*C;
00213 if ( discriminante <= EPSILON ) return 0.0;
00214
00215
00216
00217 discriminante = sqrt(discriminante);
00218 t0 = (-B-discriminante) / (2 * A);
00219
00220
00221 if ( t0 > EPSILON ) {
00222
00223 out_punto = r.origen + r.direccion * t0;
00224 if ( out_punto.z > 0 || out_punto.z < -in_h ) {
00225 return 0.0;
00226 }
00227
00228
00229
00230
00231 out_normal.x = out_punto.x;
00232 out_normal.y = out_punto.y;
00233 out_normal.z = -out_punto.z * SQUARE(in_r/in_h);
00234 out_normal.normalizar();
00235
00236 out_punto.z += in_h/2;
00237 return t0;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 return 0.0;
00254 }
00255
00256 inline double
00257 CILINDRO::interseccion_cilindro(const RAYO *in_Rayo, const double in_r,
00258 const double in_h,
00259 VECTOR &out_punto, VECTOR &out_normal)
00294 {
00295 double A, B, C, discriminante, t0 ;
00296
00297
00298 RAYO r = (*in_Rayo);
00299 r.direccion.normalizar();
00300
00301
00302 A = SQUARE(r.direccion.x) +
00303 SQUARE(r.direccion.y);
00304
00305
00306 B = 2 *
00307 ( (r.direccion.x * r.origen.x) +
00308 (r.direccion.y * r.origen.y) );
00309
00310
00311 C = SQUARE(r.origen.x) +
00312 SQUARE(r.origen.y) -
00313 SQUARE(in_r);
00314
00315
00316
00317 discriminante = SQUARE(B) - 4*A*C;
00318 if ( discriminante <= EPSILON ) return 0.0;
00319
00320
00321
00322 discriminante = sqrt(discriminante);
00323 t0 = (-B-discriminante) / (2 * A);
00324
00325
00326 if ( t0 > EPSILON ) {
00327
00328 out_punto = r.origen + r.direccion * t0;
00329
00330 if ( out_punto.z > in_h/2 || out_punto.z < -in_h/2 ) {
00331 return 0.0;
00332 }
00333
00334
00335
00336
00337 out_normal.x = out_punto.x;
00338 out_normal.y = out_punto.y;
00339 out_normal.z = 0;
00340 out_normal.normalizar();
00341 return t0;
00342 }
00343
00344 return 0.0;
00345 }
00346
00347 inline double
00348 CILINDRO::interseccion(RAYO *Rayo, VECTOR &punto,
00349 VECTOR &normal)
00356 {
00357 double t_body, t_tapa1, t_tapa2, t = 0;
00358 VECTOR p_body, p_tapa1, p_tapa2, n_body, n_tapa1, n_tapa2;
00359 int cercano = -1;
00360
00361
00362 if ( _radio2 < EPSILON && _radio1 > EPSILON ) {
00363 t_body = interseccion_cono(Rayo, _radio1, _altura, p_body, n_body);
00364 t_tapa1 = interseccion_tapa(Rayo, _radio1, -_altura/2,
00365 p_tapa1, n_tapa1);
00366
00367 if ( !IGUAL(t_body, 0.0) &&
00368 (IGUAL(t_tapa1, 0.0) || t_body < t_tapa1) ) {
00369 punto = p_body;
00370 normal = n_body;
00371 t = t_body;
00372 }
00373 else {
00374 punto = p_tapa1;
00375 normal = n_tapa1 * (-1);
00376 t = t_tapa1;
00377 }
00378 }
00379
00380
00381 if ( IGUAL(_radio1, _radio2) ) {
00382 t_body = interseccion_cilindro(Rayo, _radio1, _altura, p_body, n_body);
00383 t_tapa1 = interseccion_tapa(Rayo, _radio1, -_altura/2,
00384 p_tapa1, n_tapa1);
00385 t_tapa2 = interseccion_tapa(Rayo, _radio1, _altura/2,
00386 p_tapa2, n_tapa2);
00387
00388 if ( !IGUAL(t_body, 0.0) &&
00389 (!IGUAL(t_tapa1, 0) && t_body < t_tapa1 || IGUAL(t_tapa1, 0)) &&
00390 (!IGUAL(t_tapa2, 0) && t_body < t_tapa2 || IGUAL(t_tapa2, 0) ) ) {
00391 cercano = 1;
00392 }
00393 else if ( !IGUAL(t_tapa1, 0.0) &&
00394 (!IGUAL(t_body, 0) && t_tapa1 < t_body || IGUAL(t_body, 0)) &&
00395 (!IGUAL(t_tapa2, 0) && t_tapa1 < t_tapa2 || IGUAL(t_tapa2, 0)) ) {
00396 cercano = 3;
00397 }
00398 else {
00399 cercano = 2;
00400 }
00401
00402 if ( cercano == 1 ) {
00403 punto = p_body;
00404 normal = n_body;
00405 t = t_body;
00406 }
00407 else if ( cercano == 2 ) {
00408 punto = p_tapa2;
00409 normal = n_tapa2;
00410 t = t_tapa2;
00411 }
00412 else if ( cercano == 3 ) {
00413 punto = p_tapa1;
00414 normal = n_tapa1 * (-1);
00415 t = t_tapa1;
00416 }
00417 }
00418
00419 return t;
00420 }
00421
00422
00423
00424
00425