]> git.llucax.com Git - z.facultad/75.42/torta.git/blob - ejercicio1.c
Se corrigen los "máx" dentro de las fórmulas.
[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 max(x, y) ((x > y) ? x : y)
32
33 int esta_en(double, double, double, double, int);
34
35 int main(void) {
36     /* Declaración de variables */
37     int
38         i,
39         total,
40         radio,
41         impreso,
42         x,
43         y,
44         valores[CANT];
45     double
46         fi_cero,
47         ratio_x,
48         ratio_y,
49         fi[CANT];
50
51     /* Inicializa variables */
52     i = total = radio = impreso = x = y = 0;
53     fi_cero = ratio_x = ratio_y = 0.0;
54     for (i = 0; i < CANT; i++) {
55         valores[i] = 0;
56         fi[i] = 0.0;
57     }
58
59     /* Obtiene entrada de usuario y sale si hay error al interpretarla.
60      * TODO - hacerlo independiente de la cantidad (usando CANT),
61      *        parseando a mano.
62      */
63     printf("Ingrese la lista de números (10 máximo) separados por comas (,): ");
64     if (scanf(
65             "%i,%i,%i,%i,%i,%i,%i,%i,%i,%i\n",
66             &valores[0],
67             &valores[1],
68             &valores[2],
69             &valores[3],
70             &valores[4],
71             &valores[5],
72             &valores[6],
73             &valores[7],
74             &valores[8],
75             &valores[9]) == EOF) {
76         fprintf(stderr, "Hubo un error al interpretar su entrada de datos.\n");
77         return EXIT_FAILURE;
78     }
79
80     /* Valida datos */
81     for (i = 0; i < CANT; i++) {
82         if (valores[i] < 0) {
83             fprintf(stderr, "El valor de la posición %i es negativo.\n", i + 1);
84             return EXIT_FAILURE;
85         } else {
86             total += valores[i];
87         }
88     }
89
90     /* Calculo valores de desplazamiento de fi y el ro máximo (radio) */
91     for (i = 0; i < CANT; i++) {
92         fi[i] = (double) valores[i] * 2.0 * M_PI / (double) total;
93     }
94     radio = max(ANCHO, ALTO) / 2;
95
96     /* Calculo correcciones en x e y para que "emule" un cuadrado */
97     ratio_x = (ALTO > ANCHO) ? ((double)ALTO / (double)ANCHO) : 1.0;
98     ratio_y = (ANCHO > ALTO) ? ((double)ANCHO / (double)ALTO) : 1.0;
99
100     /* Dibuja la torta */
101     for (y = -ALTO/2; y < (ALTO/2); y++) {
102         for (x = -ANCHO/2; x < ANCHO/2; x++) {
103             impreso = 0;
104             fi_cero = 0.0;
105             for (i = 0; i < CANT; i++) {
106                 /* Se fija si cada x, y de la pantalla está en una porción de
107                  * la torta, dibujando el número que corresponde si lo es así.
108                  */
109                 if (esta_en((double)x * ratio_x,
110                             (double)y * ratio_y,
111                             fi_cero, fi[i], radio)) {
112                     printf("%i", i);
113                     impreso = 1;
114                     break;
115                 /* Si no pertenece a esta parte de la torta, actualizo el 
116                  * fi_cero sumandole el delta fi de la parte actual.
117                  */
118                 } else {
119                     fi_cero += fi[i];
120                 }
121             }
122             /* Si no se pertenece a ninguna parte, se dibuja un espacio */
123             if (!impreso) {
124                 printf(" ");
125             }
126         }
127         printf("\n"); /* Termino una línea */
128     }
129
130     /* Sale con éxito */
131     return EXIT_SUCCESS;
132
133 }
134
135 int esta_en(double x, double y, double fi_cero, double fi_delta, int radio) {
136     double ro = sqrt(x*x + y*y);
137     double fi = atan2(y, x) + M_PI;
138     double fi_fin = fi_cero + fi_delta;
139     /* Se fija si el fi y ro actuales están en los rangos
140      * NOTA: la comparación se hace como float para evitar pequeños errores
141      * de redondeo (las operaciones se hacen en double para que sean más
142      * precisas y las comparaciones en float para que sean más "flexibles").
143      */
144     return
145         ((float)ro <= (float)radio)
146         && ((float)fi >= (float)fi_cero)
147         && ((float)fi <= (float)fi_fin);
148 }
149
150 /* $Id$ */