Tema 3 3.1 Punto Tema 3: Primitivas de Salida Dibujo de un píxel, cálculo de la posición de memoria Cálculo del bit, máscara, operaciones AND, OR y NOT Modos CGA, EGA, VGA, SVGA, etc… Optimización de operaciones Tarjetas actuales comandos y ejecución por hardware 1 3.2 Líneas Tema 3: Primitivas de Salida a) Algoritmo Básico Incremental Función explícita de la línea: y =mx+B Algoritmo basado en DDA (Digital differential Analizer) Si se emplea coma flotante y redondeos, poco eficiente Si se emplea enteros problemas de continuidad 2 m=1 3.2 Líneas 45º Tema 3: Primitivas de Salida b) Algoritmo del punto medio (Bresenham) • • • • • Se basa en el empleo de la función implícita: • F(x,y )=ax+by +c=0 Si F(x,y)=0 el punto está en la recta Si F(x,y)>0 el punto está encima de la recta Si F(x,y)<0 el punto está debajo de la recta Hacemos el análisis para rectas de 45º o pendiente igual a uno (m=1), y luego lo extendemos a cualquier pendiente 3 Tema 3: Primitivas de Salida 3.2 Líneas M2 NE Q M0 Píxel actual P M1 E Píxel siguiente 4 3.3 Círculos Tema 3: Primitivas de Salida Algoritmo del punto medio (Bresenham) • Se basa en el empleo de la función implícita: • • • • • F(x,y )=x2+y 2-R 2=0 Si F(x,y)=0 el punto está en la curva del círculo Si F(x,y)>0 el punto está encima de la curva Si F(x,y)<0 el punto está debajo de la curva Hacemos el análisis para un octante de 0 a x=y, y hacemos simetrías de ocho puntos 5 3.3 Círculos Tema 3: Primitivas de Salida P E Píxel actual Q M0 M1 SE Píxel siguiente M2 6 3.3 Círculos Tema 3: Primitivas de Salida Primera implementación (1as diferencias) void circulo(int radio) { int x,y; float d; x=0; y=radio; d=5/4-radio; OchoPuntos(x,y); 7 Tema 3: Primitivas de Salida 3.3 Círculos while (y>x) { if (d<0) { d+=2*x+3; x++; } else { d+=2*(x-y)+5; x++; y—-; } OchoPuntos(x,y); } } 8 3.4 Elipses Tema 3: Primitivas de Salida Algoritmo del punto medio (Bresenham) • • • • • Se basa en el empleo de la función implícita: • F(x,y )=b 2x2+a 2y 2-a 2b 2=0 Si F(x,y)=0 el punto está en la curva del círculo Si F(x,y)>0 el punto está encima de la curva Si F(x,y)<0 el punto está debajo de la curva Hacemos el análisis para un cuadrante (2 regiones), y hacemos simetrías de cuatro puntos 9 3.4 Elipses b Tema 3: Primitivas de Salida Gradiente m Región 1 Región 2 -a m a -b 10 Tema 3: Primitivas de Salida 3.5 Otras Curvas Algoritmo del punto medio (Bresenham) • Se basa en el empleo de la función implícita: • F(x,y )=Ax2+By 2+Cxy +Dx+Ey +F=0 • Examinando el discriminante: • B2-4A C 0 0 0 generamos elipses generamos parábolas generamos hiperbolas 11 Tema 3: Primitivas de Salida 3.6 Atributos de Primitivas Se basa en el uso de la brocha (Brush) y lápiz (Pen) 1. Color (R,G,B) 2. Grosor 3. Estilo 4. Terminaciones 5. Patrón de relleno • • Pixmap Bitmap 12 3.7 Otras primitivas Tema 3: Primitivas de Salida Rectángulos, Polígonos … (son líneas) Texto: • • • Bitmaps: mapas de bits Vectoriales (TrueType, OpenType): combinación de curvas de bezier, polilíneas y algoritmos de relleno Atributos especiales: • Tipo de letra (Arial, Courier, Times New Roman …) • Tamaño (puntos) • Modificadores (negrita, itálica, superíndice, subrayada…) 13 3.7 Antialising Tema 3: Primitivas de Salida Sobremuestreo de puntos Se dibuja sobre un raster virtual de 4x4 o 9x9 y luego se suma y se hace el promedio de cada zona para calcular el píxel final, con el % del color original Aceleración por hardware, suma ponderada de los pesos de los píxeles (postproceso) Raytracing (lanzar más de 1 rayo por píxel) 14 Tema 3: Primitivas de Salida 3.7 Antialising 15 Tema 3: Primitivas de Salida 3.8 Relleno de Primitivas Tipo Vectorial Tipo Raster • Rectángulos, Círculos, Elipses, etc. • Algoritmo General de Polígonos • Regiones y Áreas 4 y 8 Conectadas • Semilla recursivo • Semilla iterativo 16 3.8 Relleno de Primitivas Rectángulos Tema 3: Primitivas de Salida Para el relleno de rectángulos empleamos el relleno de memoria de video con funciones del estilo a: • void • *memset(void *s, int c, size_t n); donde s es un puntero a la memoria, c el valor a rellenar y n el número de bytes a rellenar. Nunca se emplea la función línea de Bresenham puesto que ésta es muy ineficiente y la idea es aprovechar al máximo las coherencias, debemos epmlear máscaras para el borde derecho e izquierdo y relleno de bytes completos para el interior. 17 3.8 Relleno de Primitivas Círculos Tema 3: Primitivas de Salida La idea para rellenar círculos es bien sencilla, en vez de dibujar 8 puntos rellenamos 4 líneas. Para hacerlo correctamente debemos evitar pintar cada píxel más de una vez, puesto que si hacemos operaciones binarias, se hará mal, por ejemplo en el caso de un XOR 18 3.8 Relleno de Primitivas Elipses Tema 3: Primitivas de Salida En este caso, en vez de dibujar 4 puntos rellenamos 2 líneas. Aquí debemos evitar también pintar más de una vez un píxel, hay que estudiar los casos particulares Región 1 Región 2 19 3.8 Tema 3: Primitivas de Salida Relleno de Primitivas Polígonos Algoritmo General de Relleno de Polígonos 1 6 2 5 3 4 20 3.8 Tema 3: Primitivas de Salida Relleno de Primitivas Áreas y Fronteras Las fronteras son zonas limitadas por un contorno del mismo color Frontera 4-Conectada Frontera 8-Conectada Las áreas son zonas donde los píxeles contiguos son del mismo color Área 8-Conectada Área 4-Conectada 21 3.8 Tema 3: Primitivas de Salida Relleno de Primitivas Relleno Semilla Recursivo El relleno recursivo comprueba un pixel y si no está relleno lo pinta y hace 4 u 8 llamadas recursivas a los píxeles adyacentes, sencillo pero muy ineficiente Área 4-Conectada void Rellenar(int x, int y, color cf, color cr) { if (LeerPixel(x, y) == cf) { PintarPixel(x, y, cr); Rellenar(x, y+1, cf, cr); Rellenar(x, y-1, cf, cr); Rellenar(x+1, y, cf, cr); Rellenar(x-1, y, cf, cr); } } 22 3.8 El relleno iterativo aprovecha las distintas coherencias al máximo, y evita la pila recursiva con una pila propia que rellena de forma más “inteligente” Frontera 8-Conectada Tema 3: Primitivas de Salida Relleno de Primitivas Relleno Semilla Iterativo 23 3.8 Tema 3: Primitivas de Salida Relleno de Primitivas Relleno Semilla Iterativo Una vez rellenada la línea entre xi y xd, se buscan nuevos puntos semilla, sin sobrepasar dichos límites, en la línea superior e inferior, siguiendo el criterio de punto candidato a semilla . S1 S2 24