El algoritmo de línea de Xiaolin Wu es un algoritmo para suavizar las líneas .
El algoritmo de línea de Xiaolin Wu fue presentado en el artículo "Una técnica de antialiasing eficiente" en la edición de julio de 1991 de Computer Graphics , así como en el artículo "Antialiasing rápido" en la edición de junio de 1992 de Dr. Dobb's Journal .
El algoritmo de Bresenham dibuja líneas con gran rapidez, pero no realiza anti-aliasing. Además, no puede manejar ningún caso en el que los puntos finales de la línea no se encuentren exactamente en puntos enteros de la cuadrícula de píxeles. Un enfoque ingenuo para anti-aliasing de la línea llevaría muchísimo tiempo. El algoritmo de Wu es comparativamente rápido, pero sigue siendo más lento que el algoritmo de Bresenham. El algoritmo consiste en dibujar pares de píxeles a lo largo de la línea, cada uno coloreado según su distancia a la línea. Los píxeles en los extremos de la línea se manejan por separado. Las líneas de menos de un píxel de longitud se manejan como un caso especial.
Xiaolin Wu presentó una extensión del algoritmo para dibujar círculos en el libro Graphics Gems II . Así como el algoritmo de dibujo de líneas reemplaza al algoritmo de dibujo de líneas de Bresenham, el algoritmo de dibujo de círculos reemplaza al algoritmo de dibujo de círculos de Bresenham.
La gráfica de función ( x , y , c ) es Grafique el píxel en ( x , y ) con brillo c ( donde 0 ≤ c ≤ 1 ) // parte entera de xLa función ipart ( x ) es volver piso ( x ) La función redondear ( x ) es devolver ipart ( x + 0.5 ) // parte fraccionaria de xLa función fpart ( x ) es devolver x - ipart ( x ) La función rfpart ( x ) es devolver 1 - fpart ( x ) La función drawLine ( x0 , y0 , x1 , y1 ) es función booleana empinada := abs ( y1 - y0 ) > abs ( x1 - x0 ) Si es empinado entonces intercambiar ( x0 , y0 ) intercambiar ( x1 , y1 ) terminar si Si x0 > x1 entonces intercambiar ( x0 , x1 ) intercambiar ( y0 , y1 ) terminar si dx := x1 - x0 dy := y1 - y0 si dx == 0.0 entonces gradiente := 1.0 demás gradiente := dy / dx terminar si // manejar el primer punto final xend := redondear ( x0 ) yend := y0 + gradiente * ( xend - x0 ) xgap := rfpart ( x0 + 0.5 ) xpxl1 := xend // esto se usará en el bucle principal ypxl1 := ipart ( yend ) Si es empinado entonces gráfico ( ypxl1 , xpxl1 , rfpart ( yend ) * xgap ) gráfico ( ypxl1 + 1 , xpxl1 , fpart ( yend ) * xgap ) demás gráfico ( xpxl1 , ypxl1 , rfpart ( yend ) * xgap ) gráfico ( xpxl1 , ypxl1 + 1 , fpart ( yend ) * xgap ) terminar si intery := yend + gradient // primera intersección y para el bucle principal // manejar el segundo punto final xend := redondear ( x1 ) yend := y1 + gradiente * ( xend - x1 ) xgap := fpart ( x1 + 0.5 ) xpxl2 := xend //esto se usará en el bucle principal ypxl2 := ipart ( yend ) Si es empinado entonces gráfico ( ypxl2 , xpxl2 , rfpart ( yend ) * xgap ) gráfico ( ypxl2 + 1 , xpxl2 , fpart ( yend ) * xgap ) demás gráfico ( xpxl2 , ypxl2 , rfpart ( yend ) * xgap ) gráfico ( xpxl2 , ypxl2 + 1 , fpart ( yend ) * xgap ) terminar si // bucle principal Si es empinado entonces para x desde xpxl1 + 1 hasta xpxl2-1 hacer comenzar trama ( ipart ( intery ) , x , rfpart ( intery )) trama ( ipart ( intery ) + 1 , x , fpart ( intery )) interesante := interesante + gradiente fin demás para x desde xpxl1 + 1 hasta xpxl2-1 hacer comenzar trama ( x , ipart ( intery ) , rfpart ( intery )) trama ( x , ipart ( intery ) + 1 , fpart ( intery )) interesante := interesante + gradiente fin terminar si función final