Sunday, May 11, 2008

Ejercicio de programación en Delphi

Hace mucho tiempo, circa 1993, escribí un programa para desplegar un texto en modo espiral. Ahora, en mi curso de proceso digital de imágenes, los alumnos tienen que "torcer" una imagen, de manera que se vea como si se le hubiese aplicado una espiral. El efecto se ve como en la imagen de Ken Thompson (uno de los creadores de Unix), que ilustra este artículo.

Así, lo primero que les dije a mis estudiantes es que deberían intentar primero dibujar una espiral en la pantalla para que así, cuando pasaran a la imagen a procesar, simplemente tomaran el pixel de cada punto en particular y lo pusieran donde los cálculos de la espiral indicaran. Por lo tanto, se me ocurrió que para hacerles la labor menos ingrata, escribieran un programa que no sólo pintara la espiral, sino que, por ejemplo, desplegara un archivo de texto de forma espiral para que así se diesen mejor idea de lo que había que hacer.

Hoy se me ocurrió escribir el programa y me llevó algo así como media hora, incluyendo la escritura de la documentación correspondiente:
Cómo hacer espirales en la computadora

¿Cómo es que se hace una espiral? ¿Qué ecuación formula con precisión este tipo de comportamiento en una curva? Este tipo de pregunta fueron contestadas por los matemáticos hace muchos siglos y nos muestran el gran poder del ser humano para buscar, indagar y llegar a conclusiones sobre prácticamente cualquier tema.

Para entender cómo se crean las espirales, hay que considerar la creación de un círculo, el cual se genera poniendo un punto fijo y una distancia del mismo. Todos los puntos alrededor de ese punto fijo a la distancia establecida generan simplemente un círculo perfecto. con ese mismo criterio podemos considerar la creación de una espiral. Aquí, lo que hacemos es cambiar paso a paso el radio mientras vamos pintando el círculo. Si el radio se modifica monotónicamente de forma creciente o decreciente, lo que formamos no es un círculo, sino una espiral.

En coordenadas polares (r, Teta) la espiral (que se llama de Arquímedes), puede ser descrita por la ecuación siguiente:

r=a+b(teta)

siendo a y b números reales. Cuando el parámetro a cambia, la espiral gira, mientras que b
controla la distancia en giros sucesivos. Arquímedes describió esta espiral en su libro De las Espirales.

Pues bien, con esta fórmula podemos hacer un programa que pinte una espiral. No obstante, para hacerlo más lúdico el ejercicio, intentemos desplegar un texto de manera espiral, aplicando la fórmula de Arquímedes.

Cabe destacar que un problema inicial que se presenta es que las espirales normalmente se
describen en coordenadas polares, porque así es más simple de entender, pero en los programas de computadoras, normalmente usamos coordenadas cartesianas, por lo que hay que hacer la conversión de Polares a Cartesianas. Eso se hace con el siguiente procedimiento:

procedure Polares2Cartesianas(r, teta : real; var x1, y1 : real); begin
x1 := R * cos(degtorad(teta));
y1 := R * sin(degtorad(Teta));

end;


degtorad es una función intrínseca de Delphi que convierte grados a radianes, sistema que usa normalmente la computadora. sin y cos son seno y coseno respectivamente, R es el radio y teta
es el ángulo que deseamos calcular. ¿Qué tenemos que hacer entonces? Los pasos a seguir serían:

  • Escribamos el procedimiento de Polares a Cartesianas (ver arriba)
  • Abrimos un archivo de texto el cual desplegaremos de modo espiral
  • Para cada caracter del texto calculamos un punto en la espiral y lo convertimos a cartesianas. Una vez hecho esto, lo desplegamos en la pantalla.
  • Despleguemos de esta manera hasta llenar la pantalla. Una vez hecho esto, avisamos al usuario para que pueda continuar desplegando o bien, cancele el proceso realizado.

El código que procesa el texto en espiral a continuación:

var C : char;
i : integer;

r,
teta : real;
x1, y1 : real;
Cont : integer;

modo : boolean;

begin

fin := FALSE;

r := 4;

teta := 0;

Cont := 0;

repeat
inc(Cont);
if Cont mod 5 = 0 then modo := FALSE
else modo := TRUE;

teta := teta + 1.0;
r := r + 0.10;
Polares2Cartesianas(r,teta,x1,y1);

if modo = FALSE then
begin

read(T,C); //leo caracter del texto...

Image1.Canvas.Font.Size := 14;

Image1.Canvas.Font.Style := [fsbold];

Image1.Canvas.Font.Name := 'Courier new';
Image1.Canvas.TextOut(trunc(x1) + Image1.Picture.Width div 2,
trunc(y1) + Image1.Picture.Height div 2,
C);
Application.ProcessMessages;
end;

if Cont > 3000 then

begin

Cont := 0;
r := 4;
teta := 0;
Form2.ShowModal;
Image1.Picture := nil; //esto limpia la imagen...
end;
until ((Eof(T)) or (fin=TRUE));
CloseFile(T);

end;



Como puede verse, el problema es realmente fácil de resolver. Basta con saber la expresión matemática de las espirales para poder realizar -quizás en una media hora- el programa que ahora está usted usando.

A quien le interese el programa (incluye código fuente en Delphi), escríbame a morsa@la-morsa.com y se lo envío.

No comments: