00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "core/simul/curva.h"
00023 #include "arreglo.cc"
00024
00025 #include <string.h>
00026
00027
00028
00029
00030
00031 #define ESPERO_CP(tipo, msg) \
00032 if ( tipo_token != (tipo) ) { \
00033 fprintf(stderr, "<CURVA_PARAMETRICA> ERROR: Esperaba %s y recibi [%s].\n", \
00034 (msg), cad); fflush(stderr); return FALSE; \
00035 }
00036
00037
00038
00039
00040
00041
00042 void
00043 CURVA::set_tiempo(double tiempo)
00044 {
00045 t = tiempo;
00046 }
00047
00048 void
00049 CURVA::actualizar(void)
00050 {
00051 ;
00052 }
00053
00054
00055
00056
00057
00058 SEGMENTO_DE_CURVA_PARAMETRICA::SEGMENTO_DE_CURVA_PARAMETRICA()
00059 {
00060 tiempo_final = 1;
00061 }
00062
00063 VECTOR
00064 SEGMENTO_DE_CURVA_PARAMETRICA::evaluar(double t)
00065 {
00066 VECTOR v;
00067
00068 v.x = x_t.evaluar(t);
00069 v.y = y_t.evaluar(t);
00070 v.z = z_t.evaluar(t);
00071 return v;
00072 }
00073
00074 BOOLEAN
00075 SEGMENTO_DE_CURVA_PARAMETRICA::leer(TOKENIZADOR *Sabiondo)
00076 {
00077 char cad[1000];
00078 int tipo_token = TK_DESCONOCIDO, pos;
00079 BOOLEAN con_x = FALSE, con_y = FALSE, con_z = FALSE;
00080 EXPRESION_REGULAR tmp;
00081
00082
00083 pos = 2;
00084 while ( tipo_token != TK_CERRAR) {
00085 tipo_token = Sabiondo->siguiente_token(cad);
00086 switch ( pos ) {
00087 case 2: ESPERO_CP(TK_ABRIR, "\"{\""); pos++; break;
00088 default:
00089 if ( tipo_token == TK_CERRAR ) break;
00090 ESPERO_CP(TK_IDENTIFICADOR, "un identificador (3)");
00091 if ( strcmp(cad, "tiempo_final") == 0 ) {
00092 tipo_token = Sabiondo->siguiente_token(cad);
00093 ESPERO_CP(TK_CADENA, "una cadena (expresion regular)");
00094 des_comille(cad);
00095 tmp.init(cad);
00096 tiempo_final = tmp.evaluar(0);
00097 }
00098 else if ( strcmp(cad, "x") == 0 ) {
00099 tipo_token = Sabiondo->siguiente_token(cad);
00100 ESPERO_CP(TK_CADENA, "una cadena (funcion x(t))");
00101 des_comille(cad);
00102 if ( !x_t.init(cad) ) return FALSE;
00103 con_x = TRUE;
00104 }
00105 else if ( strcmp(cad, "y") == 0 ) {
00106 tipo_token = Sabiondo->siguiente_token(cad);
00107 ESPERO_CP(TK_CADENA, "una cadena (funcion y(t))");
00108 des_comille(cad);
00109 if ( !y_t.init(cad) ) return FALSE;
00110 con_y = TRUE;
00111 }
00112 else if ( strcmp(cad, "z") == 0 ) {
00113 tipo_token = Sabiondo->siguiente_token(cad);
00114 ESPERO_CP(TK_CADENA, "una cadena (funcion z(t))");
00115 des_comille(cad);
00116 if ( !z_t.init(cad) ) return FALSE;
00117 con_z = TRUE;
00118 }
00119 ;
00120 break;
00121 }
00122 }
00123
00124
00125 if ( !con_x || !con_y || !con_z) {
00126 fprintf(stderr, "<SEGMENTO_DE_CURVA_PARAMETRICA> ERROR: Falta una "
00127 "EXPRESION_REGULAR\n");
00128 fflush(stderr);
00129 return FALSE;
00130 }
00131
00132 return TRUE;
00133 }
00134
00135
00136
00137
00138
00139 CURVA_PARAMETRICA::CURVA_PARAMETRICA() : arr_segmentos(1)
00140 {
00141 tiempo_inicial = 0;
00142 tiempo_final = 0;
00143 tipo_movimiento = TMC_STOP;
00144 }
00145
00146 CURVA_PARAMETRICA::~CURVA_PARAMETRICA()
00147 {
00148
00149 }
00150
00151 static VECTOR TMP_vector;
00152
00153 BOOLEAN
00154 CURVA_PARAMETRICA::consultar_variable(const char *nombre_variable,
00155 int &tipo, void **ref)
00156 {
00157 TMP_vector = evaluar();
00158
00159 if ( strcmp(nombre_variable, "x") == 0 ) {
00160 tipo = T_FLOAT; (*ref) = &TMP_vector.x; return TRUE;
00161 }
00162 else if ( strcmp(nombre_variable, "y") == 0 ) {
00163 tipo = T_FLOAT; (*ref) = &TMP_vector.y; return TRUE;
00164 }
00165 else if ( strcmp(nombre_variable, "z") == 0 ) {
00166 tipo = T_FLOAT; (*ref) = &TMP_vector.z; return TRUE;
00167 }
00168 else if ( strcmp(nombre_variable, "valor") == 0 ) {
00169 tipo = T_VECTOR; (*ref) = &TMP_vector; return TRUE;
00170 }
00171 ;
00172 return FALSE;
00173 }
00174
00175 BOOLEAN
00176 CURVA_PARAMETRICA::leer(TOKENIZADOR *Sabiondo)
00177 {
00178 char cad[1000];
00179 int tipo_token = TK_DESCONOCIDO, pos;
00180 SEGMENTO_DE_CURVA_PARAMETRICA *Segmento;
00181 EXPRESION_REGULAR tmp;
00182
00183
00184 pos = 1;
00185 while ( tipo_token != TK_CERRAR) {
00186 tipo_token = Sabiondo->siguiente_token(cad);
00187 switch ( pos ) {
00188 case 1:
00189 ESPERO_CP(TK_CADENA, "una cadena");
00190 if ( strlen(cad) > MAX_CAD-1 ) cad[MAX_CAD-1] = '\0';
00191 des_comille(cad);
00192 set_nombre(cad);
00193 pos++;
00194 break;
00195 case 2: ESPERO_CP(TK_ABRIR, "\"{\""); pos++; break;
00196 default:
00197 if ( tipo_token == TK_CERRAR ) break;
00198 ESPERO_CP(TK_IDENTIFICADOR, "un identificador (3)");
00199
00200 if ( strcmp(cad, "SEGMENTO") == 0 ) {
00201 Segmento = new SEGMENTO_DE_CURVA_PARAMETRICA();
00202 if ( !Segmento || !Segmento->leer(Sabiondo) ) {
00203 return FALSE;
00204 }
00205 arr_segmentos.anx(Segmento);
00206 }
00207 else if ( strcmp(cad, "tiempo_inicial") == 0 ) {
00208 tipo_token = Sabiondo->siguiente_token(cad);
00209 ESPERO_CP(TK_CADENA, "una cadena (expresion regular)");
00210 des_comille(cad);
00211 tmp.init(cad);
00212 tiempo_inicial = tmp.evaluar(0);
00213 }
00214 else if ( strcmp(cad, "tipo_movimiento") == 0 ) {
00215 tipo_token = Sabiondo->siguiente_token(cad);
00216 ESPERO_CP(TK_IDENTIFICADOR, "un identificador (tipo)");
00217 if ( strcmp(cad, "STOP") == 0 ) {
00218 tipo_movimiento = TMC_STOP;
00219 }
00220 else if ( strcmp(cad, "BACKWARD") == 0 ) {
00221 tipo_movimiento = TMC_BACKWARD;
00222 }
00223 else {
00224 tipo_movimiento = TMC_REPLAY;
00225 }
00226 }
00227 ;
00228 break;
00229 }
00230 }
00231
00232
00233 if ( !arr_segmentos.tam() ) {
00234 fprintf(stderr, "<CURVA_PARAMETRICA> ERROR: No tiene sentido tener "
00235 "una curva sin segmentos!\n");
00236 fflush(stderr);
00237 return FALSE;
00238 }
00239
00240 tiempo_final = arr_segmentos[arr_segmentos.tam()-1]->tiempo_final;
00241
00242 return TRUE;
00243 }
00244
00245 VECTOR
00246 CURVA_PARAMETRICA::evaluar(void)
00247 {
00248
00249 VECTOR v(6, 6, 6);
00250 double ti = t;
00251 double residuo;
00252 int partes;
00253 double div;
00254 int i;
00255
00256 if ( ti < tiempo_inicial ) ti = tiempo_inicial;
00257
00258 div = (ti - tiempo_inicial) / (tiempo_final - tiempo_inicial);
00259 partes = (int)(floor(div));
00260 residuo = ti - (tiempo_final - tiempo_inicial) * ((double)partes)
00261 - tiempo_inicial;
00262
00263
00264 if ( tipo_movimiento == TMC_STOP ) {
00265 if ( ti > tiempo_final ) ti = tiempo_final;
00266 }
00267 else if ( tipo_movimiento == TMC_REPLAY ) {
00268 ti = residuo + tiempo_inicial;
00269 }
00270 else if ( tipo_movimiento == TMC_BACKWARD ) {
00271 if ( (partes % 2) == 0 ) {
00272 ti = residuo + tiempo_inicial;
00273 }
00274 else {
00275 ti = tiempo_final - residuo;
00276 }
00277 }
00278 ;
00279
00280 for ( i = 0; i < arr_segmentos.tam(); i++ ) {
00281
00282 if ( ti <= arr_segmentos[i]->tiempo_final + EPSILON ) {
00283 v = arr_segmentos[i]->evaluar(ti);
00284 return v;
00285 }
00286 }
00287
00288
00289 fprintf(stderr,
00290 "<CURVA_PARAMETRICA> WARNING: Inconsistencia de segmento!\n");
00291 fflush(stderr);
00292
00293 return v;
00294 }
00295
00296 void
00297 CURVA_PARAMETRICA::actualizar(void)
00298 {
00299 ;
00300 }
00301
00302
00303
00304
00305