]> git.llucax.com Git - z.facultad/75.42/torta.git/blob - ejercicio1.c
Se agrega un mensaje al pedir los valores.
[z.facultad/75.42/torta.git] / ejercicio1.c
1 /*
2  * Taller de Programación (75.42).
3  *
4  * Ejercicio Número 1 - Graficador de torta en modo texto.
5  *
6  * Copyleft (2003) Leandro Lucarella <llucare@fi.uba.ar>
7  * Puede copiar, modificar y distribuir este programa bajo los términos de
8  * la licencia GPL (http://www.gnu.org/).
9  *
10  * Creado: lun mar 24 02:21:42 ART 2003
11  *
12  * $Id$
13  */
14
15 /* bibliotecas usadas */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <math.h>
19
20 /* Constante con PI */
21 #ifndef M_PI
22 #   define M_PI 3.14159265358979323846
23 #endif
24
25 /* Constantes que indican el ancho y alto de la pantalla */
26 #define ANCHO 80
27 #define ALTO  25
28 /* Constante con la máxima cantidad de elementos aceptables */
29 #define CANT  10
30
31 #define SCANF_STRING "%i,%i,%i,%i,%i,%i,%i,%i,%i,%i\n"
32
33 #define max(x, y) ((x > y) ? x : y)
34
35 int esta_en(double, double, double, double, int);
36
37 int main(void) {
38     /* Declaración de variables */
39     int
40         i,
41         total,
42         radio,
43         impreso,
44         x,
45         y,
46         valores[CANT];
47     double
48         fi_cero,
49         ratio_x,
50         ratio_y,
51         fi[CANT];
52
53     /* Inicializa variables */
54     i = total = radio = impreso = x = y = 0;
55     fi_cero = ratio_x = ratio_y = 0.0;
56     for (i = 0; i < CANT; i++) {
57         valores[i] = 0;
58         fi[i] = 0.0;
59     }
60
61     /* Obtiene entrada de usuario y sale si hay error al interpretarla.
62      * TODO - hacerlo independiente de la cantidad (usando CANT),
63      *        parseando a mano.
64      */
65     printf("Ingrese la lista de números (10 máximo) separados por comas (,): ");
66     if (scanf(
67             SCANF_STRING,
68             &valores[0],
69             &valores[1],
70             &valores[2],
71             &valores[3],
72             &valores[4],
73             &valores[5],
74             &valores[6],
75             &valores[7],
76             &valores[8],
77             &valores[9]) == EOF) {
78         fprintf(stderr, "Hubo un error al interpretar su entrada de datos.\n");
79         return EXIT_FAILURE;
80     }
81
82     /* Valida datos */
83     for (i = 0; i < CANT; i++) {
84         if (valores[i] < 0) {
85             fprintf(stderr, "El valor de la posición %i es negativo.\n", i + 1);
86             return EXIT_FAILURE;
87         } else {
88             total += valores[i];
89         }
90     }
91
92     /* Calculo valores de desplazamiento de fi y el ro máximo (radio) */
93     for (i = 0; i < CANT; i++) {
94         fi[i] = (double) valores[i] * 2.0 * M_PI / (double) total;
95     }
96     radio = max(ANCHO, ALTO) / 2;
97
98     /* Calculo correcciones en x e y para que "emule" un cuadrado */
99     ratio_x = (ALTO > ANCHO) ? ((double)ALTO / (double)ANCHO) : 1.0;
100     ratio_y = (ANCHO > ALTO) ? ((double)ANCHO / (double)ALTO) : 1.0;
101
102     /* Dibuja la torta */
103     for (y = -ALTO/2; y < (ALTO/2); y++) {
104         for (x = -ANCHO/2; x < ANCHO/2; x++) {
105             impreso = 0;
106             fi_cero = 0.0;
107             for (i = 0; i < CANT; i++) {
108                 /* Se fija si cada x, y de la pantalla está en una porción de
109                  * la torta, dibujando el número que corresponde si lo es así.
110                  */
111                 if (esta_en((double)x * ratio_x,
112                             (double)y * ratio_y,
113                             fi_cero, fi[i], radio)) {
114                     printf("%i", i);
115                     impreso = 1;
116                     break;
117                 /* Si no pertenece a esta parte de la torta, actualizo el 
118                  * fi_cero sumandole el delta fi de la parte actual.
119                  */
120                 } else {
121                     fi_cero += fi[i];
122                 }
123             }
124             /* Si no se pertenece a ninguna parte, se dibuja un espacio */
125             if (!impreso) {
126                 printf(" ");
127             }
128         }
129         printf("\n"); /* Termino una línea */
130     }
131
132     /* Sale con éxito */
133     return EXIT_SUCCESS;
134
135 }
136
137 int esta_en(double x, double y, double fi_cero, double fi_delta, int radio) {
138     double ro = sqrt(x*x + y*y);
139     double fi = atan2(y, x) + M_PI;
140     double fi_fin = fi_cero + fi_delta;
141     /* Se fija si el fi y ro actuales están en los rangos
142      * NOTA: la comparación se hace como float para evitar pequeños errores
143      * de redondeo (las operaciones se hacen en double para que sean más
144      * precisas y las comparaciones en float para que sean más "flexibles").
145      */
146     return
147         ((float)ro <= (float)radio)
148         && ((float)fi >= (float)fi_cero)
149         && ((float)fi <= (float)fi_fin);
150 }
151
152 /* $Id$ */