GRAFICACIÓN DE PUNTOS Trazo de 1 punto: convertir una posición en particular en operación apropiada para el dispositivo de salida. Trazo de líneas: cálculo de posiciones intermedias a lo largo de la trayectoria de la línea entre dos posiciones externas específicas. Trazador análogo Generan voltajes de deflexión horizontal y vertical linealmente variables que son proporcionales a los cambios requeridos en las direcciones x y y para producir una línea tenue. Trazador digital Se basan en la ecuación de la recta y = mx + b m = y2 ! y 1 x2 ! x1 Los valores obtenidos son aproximados, consecuencia de la conversión a tipo entero, produciendo lo que se conoce como efecto escalonado el cuál se muestra en la siguiente figura. Funciones básicas » setPixel(x,y,intensidad) : cargar el valor intensidad en el búfer de estructura en una posición correspondiente a la posición de píxel x y a la línea de rastreo y. » getPixel(x,y) : recuperar el valor de intensidad en una posición correspondiente a la posición de píxel x y a la línea de rastreo y. ALGORITMOS PARA EL TRAZO DE LÍNEAS La ecuación de intersección de la pendiente cartesiana de una recta es: y = mx + b (1) m: pendiente de la línea b: intersección de y extremos: (x 1 , y1 ) y (x 2 , y2) y2 ! y 1 x2 ! x1 (2) b = y1 ! mx 1 (3) m = Trayectoria lineal entre posiciones de extremos (x 1 , y1 ) y (x 2 , y2) Los algoritmos para desplegar líneas rectas se basan en la ecuación de la recta (1) y los cálculos que se dan en las ecuaciones (2) y (3). Para cualquier x dentro del intervalo !y de y a partir de la ecuación (2) como: !y = m!x (4) de modo similar podemos obtener el intervalo !x de x correspondiente a una !y especifica como: !x = !y m (5) Segmento de línea recta con cinco posiciones de muestreo a lo largo del eje x entre x1 y y1 Las ecuaciones (1) a (5) son la base para determinar voltajes de deflexión en dispositivos análogos. Para líneas donde m < 1 , !x puede ser proporcional a un bajo voltaje de deflexión horizontal y la deflexión vertical se establece entonces de manera proporcional a !y , como (4). Para líneas cuya m > 1 , !y puede ser proporcional a un bajo voltaje de deflexión vertical y la deflexión horizontal correspondiente se establece entonces de manera proporcional a !x , como se calculo en (5). Para las líneas con m = 1 , !x = !y y los voltajes de deflexión horizontal y verticales son iguales. En todos los casos se dibuja (traza) una línea tenue de (x 1 , y1 ) a (x 2 , y2) con pendiente m . En sistemas de rastreo, las líneas se trazan con píxeles y los tamaños de paso en la dirección horizontal y vertical se limitan por las separaciones de píxel, es decir, se debe “efectuar un muestreo” de una línea en posiciones discretas y determinar el píxel mas cercano a la línea en cada posición sometida al muestreo. » Algoritmo DDA Analizador de diferencia digital (DDA; del inglés digital diferencial analyzer) es un algoritmo de línea de conversión de rastreo que se basa en el cálculo ya sea de !y o de !x , por medio de las ecuaciones (4) o (5). Se efectúa un muestreo de la línea en intervalos unitarios en una coordenada y se determina los valores enteros correspondientes más próximos a la trayectoria de la línea para la otra coordenada. 1. Una línea con m ! 0 Si m ! 1 ; se lleva a cabo un muestreo de x en intervalos unitarios ( !x = 1 ) y se calcula cada valor sucesivo de y como: yk+ 1 = y k + m (6) k: valores enteros a partir de 1 y aumenta a razón de 1 hasta que alcanza su valor final. 0 ! m ! 1 y debe ser redondeada al entero más cercano. Si m > 1 se revierten las funciones de x y y. Se realiza un muestreo de y en intervalos unitarios ( !y = 1 ) y se calcula el valor sucesivo de x como: x k+ 1 = x k + 1 m (7) (6) y (7) se basan en que las líneas deben procesarse del extremo izquierdo al derecho, si no es así entonces los incrementos serán de !x = "1 para 0 ! m ! 1 y !y = "1 para m > 1 . yk+ 1 = y k ! m (8) x k+ 1 = x k ! 1 m (9) (8) y (9) también se utilizan para líneas con m < 0 . La entrada para este algoritmo son las posiciones de píxel de los extremos. !x : dx !y : dy La diferencia con la mayor magnitud se establecerá como el valor del parámetro steps. Se inicia en (x a , ya ) , determinando las compensación necesaria para generar la posición de px siguiente a lo largo de la trayectoria de la línea. ciclo: steps veces ( dx > dy ) y ( x a < x b ) Ç x y y : 1 y m variación mas alta en dx pero x a > x b entonces !1 y !m sirven para generar el nuevo punto de la línea. Ejemplo de implementación del algoritmo DDA. procedure lineDDA(xa, ya, xb, yb: integer) var dx, dy, steps, k: integer; xIncrement, yIncrement, x, y: real; begin dx:= xb - xa; dy:= yb – ya; if abs(dx) > abs(dy) then steps:= abs(dx); else steps:= abs(dy); xIncrement:= dx/steps; yIncrement:= dy/steps; x:= xa; y:= ya; setPixel(round(x), round(y), 1); for k:=1 to steps do begin x:= x + xIncrement; y:= y + yIncrement; setPixel(round(x), round(y), 1); end; end; {lineDDA} » Algoritmo de línea de Bresenham Preciso y efectivo Convierte mediante rastreo de líneas al utilizar sólo cálculos incrementales con enteros que se pueden adaptar para desplegar circunferencias y otras curvas. Realizar un de la línea cuyo valor trayectoria muestreo para decidir cuál de dos posibles posiciones de píxel esta más próxima a la trayectoria en cada paso del muestreo. Para realizar lo anterior se prueba el signo de un parámetro entero, es proporcional a la diferencia entre las separaciones de dos posiciones de píxel de la real de la línea. Planteamiento de Bresenham Procedimiento de conversión de rastreo para líneas 0 ! m ! 1 . muestreo de x en intervalos unitarios. Inicio: (x 0 , y0 ) extremo izquierdo de 1 línea. Se pasa a cada columna sucesiva (x) y se traza el píxel cuyo valor en y de la línea de rastreo se aproxima más a la trayectoria de la línea de rastreo. Trazando el punto (x k , yk) se requiere decidir el valor de y para x k+ 1 , el siguiente píxel estará en la posición (x k+ 1 , yk) o (x k+ 1 , yk+ 1 ) . Distancia entre posiciones de píxel y las coordenadas de la posición y de la línea de muestreo x k+ 1 = x k + 1 d1 = m(x k + 1) + b (10) d1 y d2: separaciones de píxel verticales de la trayectoria de la línea matemática. d1 = y ! yk = m(x k + 1) + b ! yk d2 = yk+ 1 ! y = y k+ 1 ! m(x k + 1) ! b La diferencia entre estas dos separaciones es: d1 ! d2 = 2m(x k + 1) ! 2yk + 2b ! 1 (11) ç Parámetro de decisión Pk para el k-ésimo paso: En el algoritmo de línea se puede obtener al reordenar la ecuación (11) de modo que implique sólo cálculos de enteros. Se realiza esto al sustituir m = Pk = !x(d1 " d2) !y !x Pk = 2!y "x k #2!x " y k + C (12) donde C = 2!y + !x(2b " 1) Si yk es más cercano que yk+ 1 ( d1 < d2 ), Pk es negativo por lo que se traza el píxel inferior. Paso k+1: Pk+ 1 = 2!y "x k+ 1 #2!x " y k+ 1 + C , donde x k+ 1 =x k +1 Sustrayendo (12) Pk+ 1 ! Pk = 2"y # (x k+ 1 !x k) ! 2"x # (y k+ 1 ! yk ) + C ! C Pk+ 1 ! Pk = 2"y ! 2"x # (yk+ 1 ! y k) Se realiza un cálculo recursivo empezando con el extremo izquierdo. Para (x 0 , y0 ) : P0 = 2!y " !x Algoritmo de Bresenham para el trazo de líneas para m < 1 1. Se capturan los dos extremos de la línea y se almacena el extremo izquierdo en (x 0 , y0 ) . 2. Se carga (x 0 , y0 ) en el búfer de la estructura; es decir, se traza el primer punto. 3. Se calculan las constantes !x , !y , 2!y y 2!y " 2!x , obteniéndose el valor inicial de desición como: P0 = 2!y " 2!x 4. En cada x k a lo largo de la línea, que inicia en k=0, se efectúa la prueba siguiente: Si Pk < 0 , el siguiente punto que se debe trazar es (x k+ 1 , yk) y Pk+ 1 = Pk + 2!y De otro modo, el siguiente punto que se debe trazar es (x k+ 1 , yk+ 1 ) y Pk+ 1 = Pk + 2!y " 2!x 5. Se repite el paso 4 !x veces. Implantación del algoritmo de Bresenham procedure lineBres(xa, xb, ya, yb: integer) var dx, dy, x, y, xEnd, p: integer; begin dx:= abs(xa-xb); dy:= abs(ya-yb); p:= 2çdy-dx; {determine wich point to use as Stara, wich as end } if xa<xb then begin x:= xb; y:= yb; xEnd:= xa; end; else begin x:=xa; y:=ya; xEnd:= xb; end; setPixel(x,y,1); while x < xEnd do begin x:=x+1; if p<0 then p:= p+2çdy; else begin y:= y+1; p:= p+2ç(dy-dx); end; setPixel(x,y,1); end; end; {lineBres}