00001 //=========================================================================== 00002 //= esfera.h Marzo de 1999 = 00003 //=-------------------------------------------------------------------------= 00004 //= Definiciones de la clase ESFERA. = 00005 //= NOTA: No incluya este encabezado en los modulos. Incluya a = 00006 //= geometria.h. = 00007 //=-------------------------------------------------------------------------= 00008 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO = 00009 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN = 00010 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES, = 00011 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO, = 00012 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO, = 00013 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA = 00014 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES = 00015 //= ("ACTIVIDADES DE ALGO RIESGO"). = 00016 //=-------------------------------------------------------------------------= 00017 //= Autor original: Oscar J. Chavarro G. A.K.A. JEDILINK. Copyright (c), = 00018 //= 1997 - 2003, oscarchavarro@hotmail.com = 00019 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia = 00020 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la = 00021 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. = 00022 //=========================================================================== 00023 00024 #include "jed_defs.h" 00025 00026 #ifndef __GEOMETRIA__ 00027 #error "No incluya a esfera.h, incluya a geometria.h!" 00028 #endif 00029 00030 #ifdef VEL_ROSITA 00031 #include "toolkits/geom/geometria.h" 00032 #endif 00033 00034 class ESFERA : public PRIMITIVA_GEOMETRICA 00035 { 00036 private: 00037 double _radio; 00038 unsigned long int _lod; 00039 int _paralelos; 00040 int _meridianos; 00041 #ifdef GL_ENABLED 00042 GLUquadricObj *Textura_glu; // OJO: No usar GLU, copy-pastear algo mejor... 00043 #endif 00044 IMAGEN *imagen; 00045 00046 void activar_lod(void); 00047 public: 00048 ESFERA(double r); 00049 virtual ~ESFERA(); 00050 00051 // Servicios para raytracers y algoritmos especiales de geometria 00052 double interseccion(RAYO *Rayo, VECTOR &punto, VECTOR &normal); 00053 00054 // Otros 00055 double radio(void); 00056 void set_radio(double r); 00057 void set_lod(unsigned long int lod); 00058 void anexar_textura(IMAGEN *img); 00059 int clasificar_punto(VECTOR p); 00060 virtual GEOMETRIA *crear_copia(void); 00061 00062 void minmax(VECTOR *min, VECTOR *max); 00063 00064 #ifdef GL_ENABLED 00065 void 00066 pintar_gl(CALIDAD_VISUAL *Calidad, MATERIAL* Material, CAMARA *Camara); 00067 #endif 00068 void pintar_povray(FILE *fd); 00069 void pintar_aqz(FILE *fd); 00070 }; 00071 00072 //=========================================================================== 00073 //= Metodos inline de la clase ESFERA = 00074 //=========================================================================== 00075 00076 inline double 00077 ESFERA::interseccion(RAYO *Rayo, VECTOR &punto, VECTOR &normal) 00165 { 00166 double B, C, discriminante, t0, t1; 00167 00168 //- No se necesita calcular el termino A ya que el rayo.d es unitario --- 00169 // OJO: Asercion valida si se cumple la precondicion Q 00170 ; // A = 1; (dx^2 + dy^2 + dz^2) 00171 00172 //- Calcula el termino B ------------------------------------------------ 00173 B = 2 * 00174 ((Rayo->direccion.x * Rayo->origen.x) + 00175 (Rayo->direccion.y * Rayo->origen.y) + 00176 (Rayo->direccion.z * Rayo->origen.z)); 00177 00178 //- Calcula el termino C ------------------------------------------------ 00179 C = SQUARE(Rayo->origen.x) + 00180 SQUARE(Rayo->origen.y) + 00181 SQUARE(Rayo->origen.z) - 00182 SQUARE(_radio); // OJO: Precalcular radio^2 por eficiencia! 00183 00184 //- Calcula el discriminante. Si el discriminante no es positivo el ----- 00185 //- rayo no intersecta la esfera. retorna t = 0 - 00186 discriminante = SQUARE(B) - 4*C; 00187 if ( discriminante <= EPSILON ) return 0.0; 00188 00189 //- Resuelve la ecuacion cuadratica para las raices de la ecuacion. ----- 00190 //- (-B +/- sqrt(B^2 - 4*A*C)) / 2A. - 00191 discriminante = sqrt(discriminante); 00192 t0 = (-B-discriminante) * 0.5; 00193 00194 // OJO: Sera que siempre se cumple que t0 < t1 sin calcular a t1? 00195 00196 //- Si t0 es > 0 listo. Si no debemos calcular la otra raiz t1. --------- 00197 if ( t0 > EPSILON ) { 00198 // OJO: Aqui va el calculo del punto y la normal! 00199 punto = Rayo->origen + Rayo->direccion * t0; 00200 normal = punto; 00201 normal.normalizar(); 00202 return t0; 00203 } 00204 00205 t1 = (-B+discriminante) * 0.5; 00206 if ( t1 > EPSILON ) { 00207 // OJO: Aqui va el calculo del punto y la normal! 00208 punto = Rayo->origen + Rayo->direccion * t1; 00209 normal = punto; 00210 normal.normalizar(); 00211 // OJO: Aqui se retorna una normal que va hacia AFUERA de la 00212 // esfera, y se tiene el caso en el que el rayo se origina 00213 // dentro de la esfera. 00214 return t1; 00215 } 00216 00217 return 0.0; 00218 } 00219 00220 //=========================================================================== 00221 //= EOF = 00222 //=========================================================================== 00223