Algoritmos Graficos

27
56 0 : !(&&/ Una vez se han clarificado algunos de los fundamentos de la computación gráfica es necesario abordar el proceso de representación. En esta segunda unidad didáctica se van a encontrar los métodos para graficar las primitivas básicas: rectas, círculos, polígonos, para posteriormente abordar los correspondiente a llenado de áreas y transformaciones. Para ello se parte de la conceptualización matemática de cada una de estas primitivas, llegando al proceso de discretización necesario para su dibujo en un dispositivo como el monitor. Aunque muchos de los lenguajes computacionales ya tienen definidas en sus librerías gráficas funciones que permiten dibujar estas primitivas sin tener que incluirse en el problema de la discretización, la idea fundamental es conocer ¿cómo funciona el dibujado en el monitor, a partir de su unidad básica: el píxel? Se espera que este conocimiento redunde en un mejor manejo de los algoritmos que describen este proceso. En cada uno de los algoritmos básicos se proporciona la codificación en lenguaje Java con el fin de acercarlo a la programación. En la próxima unidad se mostrará con una mayor nivel de detalle las posibilidades de un API para la graficación. Aquí dará sus primeros pasos....pero serán esenciales. !’&’#"!1# 2/#!# Introducir al estudiante en el conocimiento de los principales algoritmos y estructuras de datos utilizados en Computación Gráfica para modelar y visualizar escenas en 2 y 3 dimensiones, como fundamento para la visualización gráfica en el computador. Proporcionar al estudiante los lineamientos tecnológicos básicos que le permitan utilizar librerías gráficas (OpenGL) en conjunto con lenguajes de programación estructurada como C. $)’!1#

Transcript of Algoritmos Graficos

Page 1: Algoritmos Graficos

56

���� �� �0� �������� ������ ��� ����:������������������

��! ��(&&�/�� Una vez se han clarificado algunos de los fundamentos de la computación gráfica es necesario abordar el proceso de representación. En esta segunda unidad didáctica se van a encontrar los métodos para graficar las primitivas básicas: rectas, círculos, polígonos, para posteriormente abordar los correspondiente a llenado de áreas y transformaciones. Para ello se parte de la conceptualización matemática de cada una de estas primitivas, llegando al proceso de discretización necesario para su dibujo en un dispositivo como el monitor. Aunque muchos de los lenguajes computacionales ya tienen definidas en sus librerías gráficas funciones que permiten dibujar estas primitivas sin tener que incluirse en el problema de la discretización, la idea fundamental es conocer ¿cómo funciona el dibujado en el monitor, a partir de su unidad básica: el píxel? Se espera que este conocimiento redunde en un mejor manejo de los algoritmos que describen este proceso. En cada uno de los algoritmos básicos se proporciona la codificación en lenguaje Java con el fin de acercarlo a la programación. En la próxima unidad se mostrará con una mayor nivel de detalle las posibilidades de un API para la graficación. Aquí dará sus primeros pasos....pero serán esenciales.

��!'�&���������'#��� "�!�1�#� � �2/#�!�#� � Introducir al estudiante en el conocimiento de los principales

algoritmos y estructuras de datos utilizados en Computación Gráfica para modelar y visualizar escenas en 2 y 3 dimensiones, como fundamento para la visualización gráfica en el computador. Proporcionar al estudiante los lineamientos tecnológicos básicos que le permitan utilizar librerías gráficas (OpenGL) en conjunto con lenguajes de programación estructurada como C.

�$)'!�1�#�

Page 2: Algoritmos Graficos

57

� Que el estudiante explique los algoritmos necesarios para el trazado de curvas en dos dimensiones, a partir del estudio de su origen matemático, geométrico y la ejemplificación utilizando librerías gráficas en conjunto con leguajes de programación. Que el estudiante programe ejercicios de llenado de áreas y transformaciones de figuras de dos dimensiones, utilizando librerías gráficas y lenguajes de programación, partiendo de la conceptualización geométrica respectiva.

��"2'!'�&��#� � El estudiante programa y utiliza algoritmos que permiten dibujar

las principales figuras geométricas de dos dimensiones. El estudiante conoce los fundamentos matemáticos de la representación de gráficos computacionales en tres dimensiones y utiliza algoritmos que las realizan.

�'!�#� � Una vez terminada esta unidad didáctica el estudiante estará

en capacidad de: Usar librerías gráficas para la construcción de gráficos computacionales. Utilizar y construir algoritmos para dibujo de gráficos en 2D y 3D. Describir el funcionamiento matemático y geométrico que permite el dibijo de gráficos en el computador.

� ��2�����&'2!(����'�����������

Page 3: Algoritmos Graficos

58

� ��(&!�#��'� 2 '���3�)'�

Individual Lectura autorregulada de la Unidad Didáctica realizando Fichas textuales, Fichas de Concepto, y Mapas Conceptuales para archivar en el portafolio. Consulta en internet sobre los temas de la unidad y publicación de preguntas en el foro de la unidad correspondiente para que sean solucionadas por el tutor o los compañeros. Sustentación individual de los programas desarrollados en pequeño grupo colaborativo. Pequeño Grupo Colaborativo Desarrollo de 2 ejercicios de programación aplicando los algoritmos de graficación en JAVA. Los enunciados serán entregados por el tutor, además se estipularán las fechas y condiciones de entrega. Grupo de Curso Por cada tipo de algoritmo que se estudia se realizará una práctica en computadores, para repasar los conceptos básicos y probar los algoritmos codificados en JAVA

��24!(������ ��� �!"�#�$%#�&�#� En este capítulo se revisan los fundamentos geométricos y matemáticos a partir de los cuales se generan los algoritmos que dibujan primitivas gráficas como líneas, circunferencias y arcos. Para su desarrollo se utilizó el capítulo correspondiente del texto de Claudio Delrieux11 y se complementa con la codificación en Java de los algoritmos. Es muy difícil escoger un conjunto de primitivas gráficas que sea adecuado para la representación de todo tipo de entidades gráficas. Sin embargo, el siguiente subconjunto en la práctica resulta suficiente:

11 DELRIEUX, Claudio. Introducción a la computación gráfica. [En línea] http://www.dc.uba.ar/people/materias/cgr/util.htm. Universidad Nacional del Sur. Departamento de Ingeniería eléctrica. [email protected].

Page 4: Algoritmos Graficos

59

Puntos: Se especifican a partir de su localización y color. Su discretización es directa, como se mencionó con anterioridad. Segmentos de recta: Son esenciales para la mayor parte de las entidades. Se especifican a partir de un par de puntos que representan sus extremos. Circunferencias: En algunos casos representar entidades curvadas con segmentos poligonales puede ser indadecuado o costoso, por lo que en la prácticas las circunferencias o círculos se adoptan como primitivas. Se especifican con la posición de su centro y su radio. Polígonos: Son indispensables para representar entidades sólidas. Se representan a partir de la secuencia de puntos que determina la poligonal de su perímetro.

�����#2'&�-�&�&���'#��'�(�����#& '!�3�&�/�� En el momento de escoger un método de discretización para una primitiva gráfica, es indispensable contar con criterios que permitan evaluar y comparar las ventajas y desventajas de las distintas alternativas. Entre todas las especificaciones posibles, podemos mencionar las siguientes: Apariencia: Es la especificación más obvia, aunque no es fácil describirla en términos formales. Normalmente se espera que un segmento de recta tenga una “apariencia recta” más allá de que se hallan escogido los pixels matemáticamente más adecuados. Tampoco debe tener discontinuidades. Debe pasar por la discretización del primer y último punto del segmento. Debe ser uniforme, etc. Simetría e invariancia geométrica: Esta especificación se refiere a que un método de discretización debe producir resultados equivalentes si se modifican algunas propiedades geométricas de la primitiva que se está discretizando. Por ejemplo, la discretización de un segmento no debe variar si dicho segmento se traslada a otra localización en el espacio, o si es rotado, etc. Simplicidad y velocidad de cómputo: Como los métodos tradicionales de discretización de primitivas se desarrollaron hace tres décadas, en momentos en que las posibilidades del hardware y software eran muy limitadas, los resultados eran muy sensibles al uso de memoria u operaciones aritméticas complejas. Por lo tanto, los métodos tienden a no depender de estructuras complejas y a ser directamente implementables en hardware específico de baja complejidad.

�����;!���#��'���#& '!�3�&�/�� Dada una primitiva gráfica a discretizar, debemos encontrar los pixeles que la representen de la manera más correcta posible. Para ello, lo más adecuado es caracterizar matemáticamente a dicha primitiva, de modo que su discretización

Page 5: Algoritmos Graficos

60

pueda efectuarse en forma sencilla. Entre los diversos métodos que pueden plantearse destacamos los dos siguientes: Evaluar su ecuación diferencial a diferencias finitas: Este método, denominado DDA (discrete diference analyzer) consiste en plantear la ecuación diferencial de la primitiva a discretizar, y luego evaluar dicha expresión a intervalos adecuados. Análisis del error: Estos métodos fueron desarrollados por Bressenham y se basan en analizar, dado un pixel que pertenece a la discretización de la primitiva, cuál es el próximo pixel que minimiza una determinada expresión que evalúa el error que comete la discretización.

��,�'�"'�!�#��'� '&!�� El análisis de los métodos de discretización de rectas parte de considerar el comportamiento esperado en determinados casos particulares. Dichos casos surgen de suposiciones específicas que simplifican el problema, pero que al mismo tiempo se pueden generalizar a todos los demás casos por medio de simetrías. Dado un segmento de recta que va de (x0; y0) a (x1; y1), se supone que: • ∆x = (x1 - x0 ) ≥ 0, • ∆y = (y1 - y0 ) ≥ 0, y • ∆x ≥ ∆y. Esto equivale a trabajar en el “octavo” del espacio de pantalla sombreado en la Figura 28, donde el origen es el pixel que corresponde a la discretización del punto (x0;y0) y la zona sombreada a los lugares donde puede ubicarse el punto (x1;y1 ).

Figura 28 Espacio designado para caracterizar la discretización de rectas

��,���'�"'�!�#��'� '&!���� �

Page 6: Algoritmos Graficos

61

Como ya se mencionó, los métodos DDA evalúan la ecuación diferencial de la primitiva a intervalos finitos. En el caso particular de los segmentos de recta, la ecuación diferencial es:

El método busca encontrar una secuencia de n + 1 puntos tales que (x0;y0) = (x0;y0); (x1;y1 ); … (xn;yn) = (x1;y1 ). La discretización de cada uno de ellos son los pixeles de la discretización del segmento. Esta propiedad, si bien es trivial, es de gran importancia porque determina que la discretización de un segmento de recta es invariante frente a transformaciones afines. Esto significa que es equivalente transformar los extremos del segmento y discretizar el segmento transformado, o discretizar primero y transformar cada punto obtenido. Sin embargo, la primera alternativa es mucho más eficiente.

Dada la ecuación diferencial y un incremento finito arbitrario , podemos pasar de un pixel dado de la secuencia al siguiente por medio de la expresión

ε determina la “frecuencia” de muestreo del segmento. Un valor muy pequeño determina que muchas muestras producirán puntos que serán discretizados al mismo pixel. Por el contrario, un valor muy grande determinaría que el segmento aparezca “punteado” en vez de ser continuo como corresponde. Un valor práctico es elegir ∆x = 1 y por lo tanto n = ∆x, es decir, la discretización tiene tantos pixeles como longitud tiene el segmento en la variable que más varía (más uno, dado que la secuencia tiene n + 1 puntos). Al mismo tiempo es fácil ver que

En la Figura 29 es posible ver el resultado de discretizar un segmento particular por el método DDA. Observese que los puntos extremos (x0; y0) a (x1;y1 ) son en efecto puntos y por lo tanto están ubicados en cualquier lugar dentro del pixel que corresponde a su discretización.

Page 7: Algoritmos Graficos

62

Figura 29 Discretización de un segmento de recta con DDA

Un algoritmo sencillo escrito en lenguaje Java que computa la discretización de un segmento de recta por el método DDA se muestra en la Figura 30. Obsérvese que se computan las variables en punto flotante, y que además se requiere una división en punto flotante que corresponde al cálculo de m. Un pequeño paréntesis para explicar algunas sentencias que pueden causar dudas: 1- Sobre el parámetro Graphics g (línea 26), corresponde al contexto gráfico de

la ventana (algo así como un lienzo) sobre el cual se dibuja. 2- La llamada al método setColor (línea 34) permite modificar el color actual con

el cual se está dibujando, se toma el color como un objeto de tipo Color que puede ser de los preterminados de Java o creado a partir de los parámetros r, g, b. Esta llamada al método setColor permite modificar el color del “lápiz” que dibuja sobre el contexto gráfico.

Figura 30 Codificación en Java del algoritmo DDA de dibujo de líneas

3- Java no tiene una sentencia básica para dibujar puntos (pixeles), en este caso se utiliza la sentencia g.drawRect (línea 35) para dibujar un rectángulo con un ancho y alto de 0, que en su ejecución se traduce a pintar un único pixel ubicado en el punto enviado como parámetro.

4- En la misma sentencia g.drawRect (línea 35) se utiliza el “casting” a enteros para lograr la discretización de las coordenadas flotantes.

Page 8: Algoritmos Graficos

63

La ejecución del algoritmo daría como resultado algo similar a lo mostrado en la Figura 31 para 3 líneas diferentes.

Figura 31 Ejecución del algoritmo DDA en Java

Para poder discretizar un segmento de recta en cualquiera de las posibilidades es necesario considerar las simetrías que se aplican. Si por ejemplo no se cumple que ∆y = (y1 - y0 ) ≥ 0, entonces hay que considerar pendientes negativas (simetría A), caso que el algoritmo de la Figura 30 realiza automáticamente. En cambio, si ∆x = (x1 - x0 ) ≥ 0, entonces es necesario decrementar a x en el ciclo e iterar mientras no sea menor que x1 (simetría B).

Por último, si no se cumple que ∆x ≥ ∆y, entonces es necesario intercambiar los roles de las variables x e y (simetría C). Cualquier combinación de situaciones se puede resolver con combinaciones de simetrías (ver Figura 32).

Figura 32 Simetrías para discretizar segmentos de recta

��,���'�"'�!�#��'� '&!�#�2� �� '##'�<�"� En el algoritmo DDA para segmentos de recta es necesario computar sumas entre las variables en punto flotante, y además se requiere una división en punto flotante para computar la pendiente. El mérito del algoritmo que vamos a presentar consiste en que todas las operaciones se realizan en aritmética entera por medio de operaciones sencillas, y por lo tanto, su ejecución es más rápida y económica, y es de fácil implementación con hardware específico.

Page 9: Algoritmos Graficos

64

El punto de partida del análisis es el siguiente. Si la discretización de los puntos extremos del segmento debe pertenecer a la discretización del segmento, entonces es conveniente efectuar la llamada al algoritmo luego de discretizar los extremos. Esto significa que (x0;y0) y (x1; y1 ),y por lo tanto ∆x y ∆y son enteros.

Figura 33 Si p pertenece a la discretización el próximo punto será E o D

Luego, si p es un pixel que pertenece a la discretización del segmento, entonces en las condiciones particulares mencionadas, el próximo pixel solamente puede ser el ubicado a la derecha (E o “hacia el este”), o el ubicado en diagonal hacia la derecha y hacia abajo (D o “en diagonal”) como se muestra en la Figura 33.

La decisión de ir hacia el paso E o D se toma en función del error que se comete en cada caso. En este algoritmo se considera que el error es la distancia entre el centro del pixel elegido y el segmento de recta, medida en dirección del eje Y positivo del espacio de pantalla (es decir, hacia abajo). Si el error en p fuese cero, entonces al ir hacia E el error pasa a ser m (la pendiente del segmento), y en D el error pasa a ser m - 1 (ver Figura 34).

Figura 34 Error al desplazarse en E

Figura 35 Elección del próximo pixel

En general, si en p el error es e, la actualización del error es: Paso a E : e = e + m Paso a D : e = e + m –1 Por lo tanto, la elección del paso E o D depende de que el valor absoluto de e+m sea o no menor que el valor absoluto de e+m-1. Expresado de otra manera, sea e

Page 10: Algoritmos Graficos

65

el error en un determinado pixel. Si e +m> 0.5 entonces el segmento de recta pasa más cerca del pixel D, y si no, pasa más cerca del pixel E (ver Figura 35). Una de las economías de cómputo del método proviene de poder evaluar el error preguntando por cero. Es fácil ver que si se inicializa el error en e = m – 0.5 entonces en cada paso hay que chequear e >0 para elegir D. La otra economía proviene de realizar manipulaciones algebraicas para efectuar un cómputo equivalente pero en aritmética entera. Como se evalúa el error por cero, multiplicar el error por una constante no afecta el resultado. Por lo tanto, multiplicamos el error por 2∆x. A partir de dicho cambio, se constatan las siguientes igualdades:

xyxy

xe ∆−∆=��

���

� −∆∆∆= 25.020

Paso a E : e = e+2∆y Paso a D: e = e+2(∆y-∆x) De esta manera todas las operaciones se efectúan en aritmética entera, con su correspondiente agilización del tiempo de procesamiento.

Figura 36 Algoritmo de Bressenham para segmentos de recta

La implementación del algoritmo de Bressenham para segmentos de recta se muestra en la Figura 36. Teniendo en cuenta que los productos por 2 en aritmética entera se efectúan con un desplazamiento a izquierda, es posible observar que el mismo utiliza operaciones elementales e implementables con hardware específico muy sencillo.

��9���#& '!�3�&�/���'�&� &(�-' '�&��#� Como en el caso de los segmentos de recta, en la discretización de circunferencias o círculos es posible trabajar un sólo segmento de la

Page 11: Algoritmos Graficos

66

circunferencia y se obtienen las demás por simetría. Igualmente se dispone de algoritmos DDA y de Bressenham para el dibujo de circunferencias. En este aparte se mostrará una adaptación del algoritmo DDA a partir de la ecuación de la circunferencia, tomado de la página internet de Roberto Albornoz12. Para poder realizar el dibujo de la circunferencia usaremos las ecuaciones de la circunferencia en coordenadas polares que son:

θcos*rx = θsen*ry =

Estas ecuaciones serán las que ocuparemos para calcular cada punto (x,y) del círculo, donde el r será obviamente el radio de círculo y θ será el ángulo que forma el radio con la parte positiva del eje x. En forma gráfica sería así:

Figura 37 Círcunferencia con coordenadas polares

El ángulo deberá estar en radianes ya que las funciones de seno y coseno que incluye Java, trabajan con los ángulos en radianes. La fórmula para transformar grados a radianes es la siguiente:

180*gra πdos

radianes =

Entonces para dibujar el círculo de un radio determinado, solamente tenemos que hacer un ciclo desde 0 hasta 360, pero con incrementos pequeños, calcular cada punto con las ecuaciones en coordenadas polares e ir dibujando cada punto. El ciclo en vez de ir de 0 a 360 (ángulos en grados) irá de 0 a 6.28 (360*3.14/180=6.28) ya que el ángulo debe estar en radianes.

12 ALBORNOZ Roberto. Programación gráfica en lenguaje C. [En línea] http://www.geocities.com/programacion_grafica/prog_graf.htm. Fecha de consulta: Septiembre de 2005.

Page 12: Algoritmos Graficos

67

Como dijimos el ciclo de 0 a 6.28 debe hacerse con incrementos pequeños, no contando de uno en uno, ya que para un círculo de radio muy grande, podrían aparecer huecos entre un punto y el siguiente, por lo tanto tenemos que usar un incremento fraccionario. El valor 0.005 produce buenos resultados. Dibujar el círculo punto a punto es una tarea un poco lenta, debido a que se debe calcular en cada punto el seno y el coseno del ángulo, y estas funcionas son muy lentas. Para solucionar esto se pueden crear tablas predefinidas o precalculadas. En la siguiente figura se muestra el código en Java que permitiría dibujar el círculo en una ventana.

Figura 38 Código en Java para el dibujo de circunferencias

Nótese que al calcular las coordenadas x e y, estamos sumándoles las coordenadas cx e cy. Esto se hace para trasladar el centro del círculo a cualquier punto que queramos. De esta forma, para dibujar un círculo solamente es necesario especificar las coordenadas del centro (cx, cy), el radio, el color del círculo y el contexto gráfico.

Figura 39 Resultado de la ejecución del algoritmo

dibujo de circunferencias

Consulta una explicación matemática de los algoritmos DDA y Bressenham para circunferencias en: DELRIEUX, Claudio. Introducción a la computación gráfica. Universidad Nacional del Sur. Departamento de Ingeniería eléctrica. [email protected].

Page 13: Algoritmos Graficos

68

��*���$()���'�2��4����#� Se considera un polígono una figura cerrada, formada a partir de varias líneas. Para la discretización de polígonos se considerarán 2 tipos de polígonos: los irregulares y los regulares, en concordancia con lo mostrado por Steven R Davidson en su curso de gráficos disponible en internet13. ��*������4����#�� '�(�� '#� La graficación de polígonos irregulares se realiza a partir de un conjunto de puntos que se unen secuencialmente, el polígono se cierra al unir el primer y último puntos. A continuación se muestra el código Java que dibujaría un polígono irregular a partir de un vector de elementos de tipo Punto y el correspondiente número de puntos.

Figura 40 Código en java para el dibujo de polígonos

Figura 41 Resultado de la ejecución del algoritmo

de dibujo de Polígonos

Cabe recordar que en Java, al igual que en C, el índice de los vectores inicia en 0. Por tanto, la primera línea se dibuja desde el primer punto (índice 0) hasta el segundo punto (índice 1), continúa del segundo al tercero (índice 2) , y así sucesivamente, hasta dibujar la línea del penúltimo punto (índice N-2) hasta el último punto del vector (índice N-1). Al finalizar el ciclo, dibuja la línea de cierre del polígono entre el último punto (índice N-1) y el primero (índice 0).

13DAVIDSON, Steven. Curso de gráficos con clase. [En línea] http://graficos.conclase.net/curso/index.php Fecha de consulta: Diciembre de 2005. [email protected]

Page 14: Algoritmos Graficos

69

Como se podrá deducir del código el objeto Punto incluye las coordenadas x e y de un punto en el plano cartesiano. ��*������4����#� '�(�� '#� Un polígono regular se compone de aristas/lados de igual longitud. Esto implica que el ángulo entre cada arista contigua es el mismo. Si trazamos un segmento del centro a un vértice y otro segmento del centro a otro vértice contiguo, entonces el ángulo entre estos dos segmentos es un divisor de 2� = 360°. En otras palabras, cada ángulo mencionado es inversamente proporcional a la cantidad de lados del polígono regular. Podemos usar la siguiente fórmula: � = 2� / N, donde � es el ángulo, y N es la cantidad de lados Crearemos polígonos regulares en base a una circunferencia que circunscribe nuestro polígono regular. Esto implica, que el centro de la circunferencia coincide con el centro geométrico de cualquier polígono regular. Para esto, necesitamos usar algunas funciones trigonométricas, junto con el ángulo ya calculado. El paso principal es averiguar la coordenada del siguiente vértice de nuestro polígono. Usaremos las siguientes fórmulas: x i = cx + r * cos( i*� ) y i = cy + r * sen( i*� ) donde: i = 0,1,2,...,N-1, r es el radio de la circunferencia, y c = (cx, cy) es la coordenada del centro geométrico de la circunferencia y del polígono. Al agregar el centro a nuestra fórmula, conseguimos mover el centro geométrico del origen (0,0) al que nosotros deseemos. En la Figura 42 se muestra el código que generaría los polígonos regulares.

Figura 42 Código en java para dibujar polígonos regulares

Page 15: Algoritmos Graficos

70

Los parámetros de entra para el método especifican el número de lados del polígono (N), el punto centro de la circunferencia (centro), el radio de la circunferencia (radio), el contexto gráfico (g) y el color. Observe que es necesario hacer un proceso de conversión a entero del dato resultante en la multiplicación del coseno del ángulo por el radio (líneas 46 y 47), ya que las coordenadas de los puntos se deben expresar como datos enteros. Los datos así calculados se utilizan en la conformación de cada vértice del polígono (línea 48). Finalmente, una vez obtenidas las coordenadas de todos los vértices del polígono se realiza la llamada al proceso de dibujarPolígonos explicado en la sección anterior (línea 50).

Figura 43 Resultado de la ejecución del algoritmo para dibujar polígonos regulares

��24!(��������'������'�% '�#� Si bien existen diversos métodos, aquí presentaremos el más económico y difundido, que se basa en encontrar la intersección de todos los lados del polígono con cada línea de barrido (a y constante), por lo que el método se denomina conversión scan del polígono. Este método es de gran importancia porque se generaliza a una clase de algoritmos denominados scan-line para resolver determinados problemas de iluminación y sombreado en tres dimensiones. Todo polígono plano puede descomponerse en triángulos. Por lo tanto el triángulo será la base del análisis de la conversión scan de polígonos en general. Para computarla es necesario dimensionar dos arreglos auxiliares de enteros minx, maxx que para cada línea de barrido almacenarán el menor y mayor x respectivamente.

Page 16: Algoritmos Graficos

71

Figura 44 Dibujo scan de un polígono

1. Inicializar minx a infinito y maxx a menos infinito. 2. Discretizar cada arista del triángulo (con DDA o Bressenham) reemplazando la sentencia de dibujado por

if (x>maxx[y]) maxx[y]=x; if (x<minx[y]) minx[y]=x;

3. Para cada y activo, graficar una línea de minx[y] a maxx[y].

��24!(���,��� ��#-� "�&���'#� Naturalmente, así como se desean dibujar gráficos, también se desea moverlos, rotarlos, cambiar su tamaño, etc. En esta sección se presentan los principales fundamentos matemáticos que subyacen al proceso de transformación de los gráficos en dos dimensiones, a partir de lo mostrado por el euitmt WWW team de la Universidad de Oviedo14. Se espera que el estudiante en su proceso de profundización realice los algoritmos que permitan hacer estas transformaciones. Una de las mayores virtudes de los gráficos generados por ordenador es la facilidad con se pueden realizar algunas modificaciones sobre las imágenes. Un gerente puede cambiar la escala de las gráficas de un informe. Un arquitecto puede ver un edificio desde distintos puntos de vista. Un cartógrafo puede cambiar la escala de un mapa. Un animador puede modificar la posición de un personaje. 14 euitmt WWW team. Dibujo asistido por ordenador. Transformaciones 2 y 3 D. [En línea] http://www.mieres.uniovi.es/egi/dao/apuntes/. Universidad de Oviedo. Campus Mieres. Fecha de consulta: Octubre de 2005.

Page 17: Algoritmos Graficos

72

Estos cambios son fáciles de realizar porque la imagen gráfica ha sido codificada en forma de números y almacenada en el interior del ordenador. Los números son susceptibles a las operaciones matemáticas denominadas transformaciones. Las transformaciones permiten alterar de una forma uniforme toda la imagen. Es un hecho que a veces es más fácil modificar toda la imagen que una porción de ella. Esto supone un complemento muy útil para las técnicas de dibujo manual, donde es normalmente más fácil modificar una pequeña porción del dibujo que crear un dibujo completamente nuevo. Es esta sección se verán transformaciones geométricas como el cambio de escala, la traslación y la rotación, como se expresan de una forma sencilla mediante multiplicaciones de matrices y se introducirán las coordenadas homogéneas con el fin de tratar de una manera uniforme las transformaciones y como anticipo de las transformaciones producidas por la perspectiva en los modelos tridimensionales.

,���� '1'� '2�#��#�$ '�"�! �&'#� Las imágenes gráficas que se han generado están compuestas por un conjunto de segmentos que están representados por las coordenadas de sus extremos. Algunos cambios en la imagen pueden ser fácilmente realizados mediante la aplicación de algunas operaciones matemáticas sobre estas coordenadas. Antes de ver algunas de las posibles transformaciones, es necesario repasar algunas de las herramientas matemáticas que se necesitarán, como la multiplicación de matrices. Para nuestro propósito, consideraremos que una matriz es un conjunto n-dimensional de números, por ejemplo:

son cuatro matrices diferentes. Supongamos que se define la matriz A como:

Entonces el elemento situado en la segundo fila y la tercera columna será A[2][3] y tendrá un valor de 6.

Page 18: Algoritmos Graficos

73

La operación matricial que más se empleará será la multiplicación de matrices. La multiplicación de matrices es algo más complicada que la simple multiplicación de dos números; supone varios productos sencillos y sumas de los elementos de la matriz. No todas las parejas de matrices pueden ser multiplicadas. Se pueden multiplicar dos matrices A y B si el número de columnas de la primera matriz A es igual al número de filas de la segunda matriz B. Por ejemplo, si escogemos como matriz A la última que hemos visto y como matriz B la siguiente:

entonces podemos multiplicar A por B porque la primera tiene tres columnas y la segunda tres filas. Al contrario que la multiplicación de números, la multiplicación de matrices no es conmutativa, es decir, aunque podemos multiplicar A por B no podemos multiplicar B por A, por que B tiene sólo dos columnas que no se corresponden con las tres filas de A. Cuando multiplicamos dos matrices se obtiene como resultado otra matriz. Esta matriz producto tendrá el mismo número de filas que la primera de las matrices que se multiplican y el mismo número de columnas que la segunda, es decir, a partir del ejemplo, la multiplicación de la matriz A3x3 con la matriz B3x2 da como resultado la matriz C3x2. Los elementos de la matriz producto C se expresan en función de los elementos de las matrices A por B mediante la siguiente fórmula:

En nuestro caso particular de C = A B

La multiplicación de matrices es una operación asociativa. Esto significa que si tenemos varias matrices para multiplicar a la vez, no importa cuales multipliquemos primero. De forma matemática: A(BC) = (AB) C Esta es una propiedad muy útil ya que permitirá combinas varias transformaciones gráficas en una sola transformación, produciendo como resultado unos cálculos más eficientes. Existe un conjunto de matrices que cuando multiplican a otra matriz, la reproducen. Por esta razón reciben el nombre de matrices identidad. Son

Page 19: Algoritmos Graficos

74

matrices cuadradas (tienen el mismo número de columnas y de filas) con todos los elementos 0 excepto los elementos de la diagonal principal, que valen todos 1. Por ejemplo

De forma matemática A = AI

,�����"$��#��'�'#&���� ¿Cómo se aplica todo esto a los gráficos? Bueno, consideremos un punto P1=[x1 y1] como una matriz de 1x2. Si la multiplicamos por una matriz T2x2, obtendremos otra matriz que puede ser interpretada como otro punto.

Por tanto, la matriz T es una aplicación entre el punto original P1 y el nuevo punto P2. Si suponemos la imagen compuesta por los vértices de un polígono. ¿Qué pasará si transformamos cada uno de los puntos mediante una multiplicación por una matriz T y dibujamos el resultado? ¿Qué aspecto tendrá esta nueva imagen? La respuesta, por supuesto, depende de los elementos de la matriz T. Si, por ejemplo, escogemos la matriz identidad entonces la imagen no se verá alterada. Sin embargo, si escogemos la matriz

entonces Cada una de las nuevas coordenadas x tiene el doble de valor que las antiguas. Las líneas horizontales serán dos veces más largas en la nueva imagen. La nueva imagen tendrá la misma altura, pero parecerá que la hemos estirado hasta alcanzar el doble del ancho original.

antes de la transformación

después de la transformación

Page 20: Algoritmos Graficos

75

En general, las transformaciones de la forma

cambian el tamaño y la proporción de la imagen. Se denominan transformaciones de escalado. Ex es el factor de escala para la coordenada x y Ey es de la coordenada y.

,�,��!�&�/�� La siguiente transformación gráfica que vamos a ver es la rotación. Para introducir esta transformación recordaremos brevemente algunos conceptos trigonométricos. Sea un punto p1=(x1, y1) y lo giramos alrededor del origen un ángulo θ para pasar a una nueva posición p2=(x2, y2). Queremos encontrar la transformación que convierte (x1, y1) en (x2, y2). Pero, antes de comprobar si alguna transformación es la adecuada, debemos saber primero que (x2, y2) debe escribirse en función de (x1, y1) y θ. Para esto es necesario recordar las razones trigonométricas de seno y coseno.

A la vista de esta figura sabemos que

Es importante señalar que cuando la longitud del segmento es la unidad

También emplearemos las siguientes relaciones trigonométricas para determinar como gira un punto:

Ahora estamos listos ya para determinar la rotación de un punto alrededor del origen.

Page 21: Algoritmos Graficos

76

A la vista de esta figura tenemos:

donde L es la distancia del punto al origen de coordenadas. Por otro lado:

que nos lleva a

De forma análoga:

dando

A la vista de estas ecuaciones podemos imaginar una matriz que relacione las coordenadas del punto original y del punto girado:

Así la matriz de transformación para una rotación en sentido contrario a las agujas del reloj de ángulo φ alrededor del origen es

Para una rotación en el sentido de las agujas del reloj, basta sustituir en la expresión anterior el valor del ángulo por −φ. Así nos queda

Page 22: Algoritmos Graficos

77

,�9���� �'����#�<�"��;�'�#�7�! �#��&�/�� Supongamos que necesitamos realizar un giro alrededor de un punto que no es el origen. Si fuésemos capaces de trasladar toda la imagen de un punto a otro de la pantalla, podríamos realizar este giro moviendo primero la imagen hasta que el centro de rotación coincida con el origen, luego realizamos la rotación y, por último, devolvemos la imagen a su posición original. Desplazar la imagen recibe el nombre de traslación. Se realiza de una forma sencilla mediante la suma a cada punto de la cantidad que vamos a mover la imagen.

En general, con el fin de trasladar un imagen (Tx, Ty), cada punto (x1, y1) se convierte en uno nuevo (x2, y2) donde

Desafortunadamente, esta forma de describir la traslación no hace uso de matrices, por lo tanto no podría ser combinada con las otras transformaciones mediante una simple multiplicación de matrices. Tal combinación sería deseable; por ejemplo, hemos visto que la rotación alrededor de un punto que no sea el origen puede realizarse mediante una traslación, una rotación u otra traslación. Sería deseable combinar estas tres transformaciones en una sola transformación por motivos de eficacia y elegancia. Una forma de hacer esto es emplear matrices 3x3 en vez de matrices 2x2, introduciendo una coordenada auxiliar w. Este método recibe el nombre de coordenadas homogéneas. En estas coordenadas, los puntos están definidos por tres coordenadas y no por dos. Así un punto (x, y) estará representado por la tripleta (xw, yw, w). Las coordenadas x e y se pueden recuperar fácilmente dividiendo los dos primeros números por el tercero respectivamente. No emplearemos la coordenada w hasta que no veamos las transformaciones tridimensionales de perspectiva. En dos dimensiones su valor suele ser 1 para simplificar. Sin embargo, lo veremos de forma general como anticipo de las transformaciones tridimensionales. En coordenadas homogéneas la matriz de cambio de escala

se convierte en

Page 23: Algoritmos Graficos

78

Si aplicamos esta matriz a un punto (xw, yw, w) obtenemos

Si dividimos ahora por el tercer valor w tenemos (Exx, Eyy) que es el punto correcto cambiado de escala.

En el caso de la matriz de rotación en sentido antihorario

se convierte, usando coordenadas homogéneas, en: Si aplicamos esta matriz a un punto (xw, yw, w) obtenemos

para dar el punto correctamente rotado La matriz de transformación para una traslación Tx, Ty en coordenadas homogéneas es

Para comprobar que esto es así apliquemos la matriz a un punto genérico

que nos da el punto trasladado .

Page 24: Algoritmos Graficos

79

,�*��!�&�/���� '�'�� ��'�(��2(�!��&(��=(�' �� Determinemos ahora la matriz de transformación para la rotación en sentido antihorario alrededor del punto (xC, yC).

Haremos esta transformación en tres pasos. Primero trasladaremos el punto (xC, yC) al origen, luego haremos la rotación alrededor del origen y, por último, devolveremos el centro de rotación a su posición original. La traslación que desplaza al punto (xC, yC) al origen es

la rotación es

y la traslación que devuelve al centro de rotación a su posición es Para transformar un punto podemos realizar la siguiente multiplicación

pero, teniendo en cuenta la propiedad asociativa de la multiplicación de matrices, podemos multiplicar todas las transformaciones primero para obtener la matriz global de transformación

Page 25: Algoritmos Graficos

80

Cabe destacar que esta matriz se puede formar también mediante una rotación inicial de ángulo θ y una traslación definida por los valores contenidos en la tercera fila.

,�+��! �#�! ��#-� "�&���'#� Las tres transformaciones de cambio de escala, rotación y traslación son las más útiles y las más usadas. Son también posibles otras transformaciones. Dado que una matriz 2x2 cualquiera

puede convertirse en una matriz 3x3 en coordenadas homogéneas como

sólo presentaremos algunas de estas transformaciones como matrices 2x2 :

reflexión respecto al eje y

reflexión respecto al eje x

Page 26: Algoritmos Graficos

81

reflexión respecto al origen

reflexión respecto a la recta y=x

reflexión respecto a la recta y=-x

deformación en el eje y

deformación en el eje x

Las primeras tres reflexiones son simples cambios de escala pero con factores negativos. Las simetrías respecto a las rectas y=x e y=-x pueden realizarse mediante un cambio de escale y un giro posterior. Es posible realizar las deformaciones mediante una secuencia de rotaciones y cambios de escala, aunque es mucho más fácil aplicar la matriz resultante. De igual forma se pueden construir transformaciones de cambio de escala y rotación a partir de las deformaciones.

�)' &�&��#� 1. Realice un programa Java que guarde en un vector las frecuencias

encontradas en el análisis de un determinado fenómeno y permita construir un gráfico de torta donde se muestren los porcentajes de cada una de las frecuencias y un histograma de frecuencias (gráfico de barras).

2. Consulte acerca del algoritmo para dibujo de curvas S-pline e impleméntelo utilizando lenguaje Java.

3. Construya el algoritmo en Java que permita hacer llenado de áreas a partir de los mostrado en el capítulo 2 de esta unidad,

4. Realice un programa en Java que permita construir los gráficos de las funciones seno y coseno, para diferentes parámetros de amplitud y período.

5. Realice un programa en Java que grafique polinomios hasta de grado 4, a partir de los coeficientes del mismo.

6. Consulte otros algoritmos para el llenado de áreas y realice una implementación usando las directivas básicas de Java.

Page 27: Algoritmos Graficos

82

�('�!'#�'��&������#� ALBORNOZ Roberto. Programación gráfica en lenguaje C. [En línea] http://www.geocities.com/programacion_grafica/prog_graf.htm . Fecha de consulta: Septiembre de 2005. DAVIDSON, Steven. Curso de gráficos con clase. [En línea] http://graficos.conclase.net/curso/index.php Fecha de consulta: Diciembre de 2005. [email protected] DELRIEUX, Claudio. Introducción a la computación gráfica. [En línea] http://www.dc.uba.ar/people/materias/cgr/util.htm. Universidad Nacional del Sur. Departamento de Ingeniería eléctrica. [email protected]. EUITMT WWW TEAM. Dibujo asistido por ordenador. Transformaciones 2 y 3 D. [En línea] http://www.mieres.uniovi.es/egi/dao/apuntes/. Universidad de Oviedo. Campus Mieres. Fecha de consulta: Octubre de 2005. Última modificación: 9 de Julio de 1999 - 13:36:26