]> git.llucax.com Git - z.facultad/75.42/euler.git/commitdiff
Prácticamente se finaliza el TP, sólo quedan pulir detalles.
authorLeandro Lucarella <llucax@gmail.com>
Mon, 25 Aug 2003 06:23:39 +0000 (06:23 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 25 Aug 2003 06:23:39 +0000 (06:23 +0000)
documentacion.h
tp1.c
tp1.h

index a5c1b2bf67f33124192c98fcffdbf505d7ec3ebe..efae98d7d1225f870cae873ac3d59c76027e06f1 100644 (file)
         \endverbatim
 
 \section resolucion Resolución.
-    El \ref main "programa principal" se divide en FIXME N tareas principales,
+    El \ref main "programa principal" se divide en 3 tareas principales,
     cada una realizada por una función particular.
 
     \subsection obtencion Obtención y validación de parámetros del usuario.
         Antes de comenzar a hacer cálculos es necesario obtener los valores de
         las \ref variables "variables" de la entrada del usuario (en este caso
-        a través de parámetros de línea de comandos). Esto es realizado
+        a través de parámetros de línea de comandos). Esta tarea es realizada
         por la función cargar_datos().
 
     \subsection integracion Integración de la ecuación diferencial.
         función y almacenándolos en el \ref Resultados "vector de resultados",
         tarea realizada por la función calcular().
 
+    \subsection impresion Impresión del gráfico por pantalla.
+        Finalmente todo lo que queda es graficar por pantalla el resultado de la
+        función. Para esto se va imprimiendo línea por línea, chequeando qué
+        punto de la función cae en cada rango de valores representados por una
+        línea. Esta tarea es realizada por la función resultados_graficar().
+
+\section conclusiones Conclusiones.
+    Realmente no se me presentaron muchos problemas para resolver el TP. El
+    único problema que tuve fue realizando el \ref impresion "gráfico", en
+    ciertas circunstancias (por problemas de redondeo) el valor máximo de la
+    función no era graficado. Esto se solucionó incluyendo una línea más al
+    gráico, con el rango que va desde el máximo de la función (en realidad desde
+    el mínimo más 20 pasos verticales) hasta el máximo más un paso vertical.
+    Es por esto que en realidad se grafican 21 pasos. Podría haber graficado 20
+    pasos pero el código quedaría menos claro (o tendría que poner la constante
+    \ref ALTO en 19 en vez de 20).
+
+    Otro detalle que cabe ser mencionado es que para valores altos del
+    \ref variables "step" (mayores a 30), la solución se vuelve inestable.
+
 */
 
diff --git a/tp1.c b/tp1.c
index f8b7c86c0924c502f8d91dc738828e7844b16250..7706605c055fde519a2db327ae1032970854adac 100644 (file)
--- a/tp1.c
+++ b/tp1.c
@@ -79,8 +79,6 @@ int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) {
             return FALSE;
     }
     /* TODO Verificar que el paso no sea cero y que tf > ti. */
-    /* XXX - sacar */
-    printf("paso = %f, tf = %f, f0 = %f\n", *paso, *tf, *f0);
     return TRUE;
 }
 
@@ -99,16 +97,14 @@ size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) {
     /* Itero paso a paso calculando el valor de la función. */
     for (i = 1; i < pasos; i++) {
         /* f(t+paso) = FUNCION(paso, f(t)) */
-        (*res)[i]       = FUNCION(paso, (*res)[i-1]);
-        /* FIXME sacar!!!! */
-        printf("i = %i, t = %.2f, f(t) = %.2f\n", i, (Real)i * paso, (*res)[i]);
+        (*res)[i]    = FUNCION(paso, (*res)[i-1]);
     }
     return pasos;
 }
 
-Real max(const Resultados* res, size_t pasos) {
-    size_t  i;
-    Real    max = (*res)[0];
+Real resultados_max(Resultados* res, size_t pasos) {
+    size_t i;
+    Real   max = (*res)[0];
     for (i = 1; i < pasos; i++) {
         if ((*res)[i] > max) {
             max = (*res)[i];
@@ -117,9 +113,9 @@ Real max(const Resultados* res, size_t pasos) {
     return max;
 }
 
-Real min(const Resultados* res, size_t pasos) {
-    size_t  i;
-    Real    min = (*res)[0];
+Real resultados_min(Resultados* res, size_t pasos) {
+    size_t i;
+    Real   min = (*res)[0];
     for (i = 1; i < pasos; i++) {
         if ((*res)[i] < min) {
             min = (*res)[i];
@@ -128,13 +124,56 @@ Real min(const Resultados* res, size_t pasos) {
     return min;
 }
 
+void inicializar_linea(char* linea, char caracter, size_t cant) {
+    size_t j;
+    for (j = 0; j < cant; j++) {
+        linea[j] = caracter;
+    }
+    linea[cant] = '\0';
+}
+
+void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) {
+    /* Máximo valor de la función. */
+    Real min;
+    /* Mínimo valor de la función. */
+    Real max;
+    /* Paso utilizado para la representación de las líneasMínimo valor de la función. */
+    Real pasoh;
+    int  i;
+    int  j;
+    char linea[ANCHO];
+    min = resultados_min(res, pasos);
+    max = resultados_max(res, pasos);
+    pasoh = (max - min) / (ALTO);
+    printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh);
+    /* Inicializa la línea. */
+    inicializar_linea(linea, blanco, MAX_PASOS);
+    /* Por cada línea a dibujar. */
+    for (i = ALTO; i >= 0; i--) {
+        /* Se fija si hay algún punto que entre en el rango. */
+        for (j = 0; j < pasos; j++) {
+            /* Si está entre en el rango a imprimir, se agrega un punto. */
+            if (((min + pasoh * i) <= (*res)[j])
+                    && ((*res)[j] < (min + pasoh * (i + 1)))) {
+                linea[j] = punto;
+            /* Si no, se lo deja en blanco. */
+            } else {
+                linea[j] = blanco;
+            }
+        }
+        printf("%8.2f _%s\n", min + pasoh * i, linea);
+    }
+}
+
 int main(int argc, const char** argv) {
     /* TODO: Declaración de variables. */
     Resultados  resultados;
     size_t      pasos;
-    Real        paso  = DEFAULT_PASO;
-    Real        tf    = DEFAULT_TF;
-    Real        f0    = DEFAULT_F0;
+    Real        paso    = DEFAULT_PASO;
+    Real        tf      = DEFAULT_TF;
+    Real        f0      = DEFAULT_F0;
+    char        punto   = '*';
+    char        blanco  = ' ';
 
     /* Obtención de datos. */
     if (!cargar_datos(argc, argv, &paso, &tf, &f0)) {
@@ -144,10 +183,13 @@ int main(int argc, const char** argv) {
 
     /* Cálculo de la solución, dejando en un array los valores de cada paso. */
     pasos = calcular(&resultados, paso, T0, tf, f0);
+    /* XXX - sacar o poner más lindo. */
+    printf("paso = %f, tf = %f, f0 = %f, pasos = %i\n", paso, tf, f0, pasos);
 
     /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array
      *       y dibujando los resultados pertinentes. */
-    /* TODO: Liberación de memoria y otras limpiezas, en caso de ser necesario. */
+    resultados_graficar(&resultados, pasos, punto, blanco);
+
     return EXIT_SUCCESS;
 }
 
diff --git a/tp1.h b/tp1.h
index 8ae9410fedcfa107c713eb5f679a63bbda481211..eb00948a46ee8adab9424b67eb5295dfe7a08046 100644 (file)
--- a/tp1.h
+++ b/tp1.h
@@ -38,6 +38,9 @@
 /** Altura (en líneas) utilizadas para dibujar el gráfico. */
 #define ALTO 20
 
+/** Ancho (en líneas) utilizadas para dibujar el gráfico. */
+#define ANCHO 70
+
 /** Tiempo inicial. */
 #define T0 0.0
 
@@ -66,7 +69,7 @@
  *       pérdida de velocidad que agrega la indirección de un llamado a una
  *       función.
  */
-#define FUNCION(paso, ft) ((ft) + (500.0 - (ft)) / 30.0 * paso)
+#define FUNCION(paso, ft) ((ft) + ((500.0 - (ft)) / 30.0) * paso)
 
 
 
@@ -112,7 +115,7 @@ void imprimir_uso(FILE* fh);
 int argtod(const char* arg, Real* var, const char* nom);
 
 /**
- * Carga los datos necesarios por el programai.
+ * Carga los datos necesarios por el \ref main "programa".
  * Obtiene los datos desde los parámetros de la línea de comandos, validándolos
  * y mostrando un mensaje de error en caso de haberlo.
  *
@@ -123,7 +126,8 @@ int argtod(const char* arg, Real* var, const char* nom);
  * \param f0   Valor inicial de la función.
  *
  * \return TRUE si se cargaron bien, FALSE si no.
- * \todo Verificar que el paso no sea cero y que tf > ti.
+ * \todo \b TODO Verificar que el paso no sea cero y que tf > ti.
+ * \todo \b TODO Agregar opciones para especificar caracter en blanco y de punto.
  */
 int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0);
 
@@ -148,7 +152,7 @@ size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0);
  *
  * \return Máximo resultado.
  */
-Real max(const Resultados* res, size_t pasos);
+Real resultados_max(Resultados* res, size_t pasos);
 
 /**
  * Devuelve el valor mínimo de los resultados.
@@ -158,7 +162,30 @@ Real max(const Resultados* res, size_t pasos);
  *
  * \return Mínimo resultado.
  */
-Real min(const Resultados* res, size_t pasos);
+Real resultados_min(Resultados* res, size_t pasos);
+
+/**
+ * Rellena una cadena de caracteres con un caracter arbitrario.
+ *
+ * \param linea    Cadena de caracteres.
+ * \param caracter Caracter utilizado para rellenar.
+ * \param cant     Cantidad de caracteres a rellenar.
+ */
+void inicializar_linea(char* linea, char caracter, size_t cant);
+
+/**
+ * Imprime un gráfico de los resultados por pantalla.
+ * Realiza un gráfico de la función por pantalla, imprimiendo línea por línea.
+ * Cada línea representa un rango de valores. En cada línea se dibuja el
+ * caracter \e punto si la función en el tiempo evaluado está en el rango de esa
+ * línea. Si no lo está se dibuja el caracter \e blanco.
+ *
+ * \param res    Vector de resultados a graficar.
+ * \param pasos  Cantidad de pasos a graficar.
+ * \param punto  Caracter utilizado para dibujar un punto de la función.
+ * \param blanco Caracter utilizado para dibujar un punto en blanco.
+ */
+void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco);
 
 /**
  * Programa principal.