From: Leandro Lucarella Date: Tue, 25 Mar 2003 04:14:11 +0000 (+0000) Subject: Se agrega la materia Taller de Programación I (75.42). X-Git-Tag: svn_import~5 X-Git-Url: https://git.llucax.com/z.facultad/75.42/torta.git/commitdiff_plain/dc885c7cbc53149adb0df17a0d95ed8c57e76543 Se agrega la materia Taller de Programación I (75.42). --- dc885c7cbc53149adb0df17a0d95ed8c57e76543 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..64c3bb8 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +# Opciones para el compilador. +CFLAGS=-ansi -pedantic -Wall -g + +# Opciones para el linker. +LDFLAGS=-lm + +# Programa a compilar. +TARGETS=ejercicio1 + +# Regla por defecto. +all: $(TARGETS) + +# Regla para borrar. +clean: + @echo "Limpiando..." + @rm -fv $(TARGETS) *.o core diff --git a/ejercicio1.c b/ejercicio1.c new file mode 100644 index 0000000..97a621c --- /dev/null +++ b/ejercicio1.c @@ -0,0 +1,151 @@ +/* + * Taller de Programación (75.42). + * + * Ejercicio Número 1 - Graficador de torta en modo texto. + * + * Copyleft (2003) Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: lun mar 24 02:21:42 ART 2003 + * + * $Id$ + */ + +/* bibliotecas usadas */ +#include +#include +#include + +/* Constante con PI */ +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +/* Constantes que indican el ancho y alto de la pantalla */ +#define ANCHO 80 +#define ALTO 25 +/* Constante con la máxima cantidad de elementos aceptables */ +#define CANT 10 + +#define SCANF_STRING "%i,%i,%i,%i,%i,%i,%i,%i,%i,%i\n" + +#define max(x, y) ((x > y) ? x : y) + +int esta_en(double, double, double, double, int); + +int main(void) { + /* Declaración de variables */ + int + i, + total, + radio, + impreso, + x, + y, + valores[CANT]; + double + fi_cero, + ratio_x, + ratio_y, + fi[CANT]; + + /* Inicializa variables */ + i = total = radio = impreso = x = y = 0; + fi_cero = ratio_x = ratio_y = 0.0; + for (i = 0; i < CANT; i++) { + valores[i] = 0; + fi[i] = 0.0; + } + + /* Obtiene entrada de usuario y sale si hay error al interpretarla. + * TODO - hacerlo independiente de la cantidad (usando CANT), + * parseando a mano. + */ + if (scanf( + SCANF_STRING, + &valores[0], + &valores[1], + &valores[2], + &valores[3], + &valores[4], + &valores[5], + &valores[6], + &valores[7], + &valores[8], + &valores[9]) == EOF) { + fprintf(stderr, "Hubo un error al interpretar su entrada de datos.\n"); + return EXIT_FAILURE; + } + + /* Valida datos */ + for (i = 0; i < CANT; i++) { + if (valores[i] < 0) { + fprintf(stderr, "El valor de la posición %i es negativo.\n", i + 1); + return EXIT_FAILURE; + } else { + total += valores[i]; + } + } + + /* Calculo valores de desplazamiento de fi y el ro máximo (radio) */ + for (i = 0; i < CANT; i++) { + fi[i] = (double) valores[i] * 2.0 * M_PI / (double) total; + } + radio = max(ANCHO, ALTO) / 2; + + /* Calculo correcciones en x e y para que "emule" un cuadrado */ + ratio_x = (ALTO > ANCHO) ? ((double)ALTO / (double)ANCHO) : 1.0; + ratio_y = (ANCHO > ALTO) ? ((double)ANCHO / (double)ALTO) : 1.0; + + /* Dibuja la torta */ + for (y = -ALTO/2; y < (ALTO/2); y++) { + for (x = -ANCHO/2; x < ANCHO/2; x++) { + impreso = 0; + fi_cero = 0.0; + for (i = 0; i < CANT; i++) { + /* Se fija si cada x, y de la pantalla está en una porción de + * la torta, dibujando el número que corresponde si lo es así. + */ + if (esta_en((double)x * ratio_x, + (double)y * ratio_y, + fi_cero, fi[i], radio)) { + printf("%i", i); + impreso = 1; + break; + /* Si no pertenece a esta parte de la torta, actualizo el + * fi_cero sumandole el delta fi de la parte actual. + */ + } else { + fi_cero += fi[i]; + } + } + /* Si no se pertenece a ninguna parte, se dibuja un espacio */ + if (!impreso) { + printf(" "); + } + } + printf("\n"); /* Termino una línea */ + } + + /* Sale con éxito */ + return EXIT_SUCCESS; + +} + +int esta_en(double x, double y, double fi_cero, double fi_delta, int radio) { + double ro = sqrt(x*x + y*y); + double fi = atan2(y, x) + M_PI; + double fi_fin = fi_cero + fi_delta; + /* Se fija si el fi y ro actuales están en los rangos + * NOTA: la comparación se hace como float para evitar pequeños errores + * de redondeo (las operaciones se hacen en double para que sean más + * precisas y las comparaciones en float para que sean más "flexibles"). + */ + return + ((float)ro <= (float)radio) + && ((float)fi >= (float)fi_cero) + && ((float)fi <= (float)fi_fin); +} + +/* $Id$ */