Xiaolin Wu's line algorithm: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
Line 3:
[[Bresenham's line algorithm|Bresenham's algorithm]] draws lines extremely quickly, but it cannot perform anti-aliasing. In addition, it cannot handle the case where the line endpoints do not lie exactly on integer points of the pixel grid. A naïve approach to anti-aliasing the line would take an extremely long time, but Wu's algorithm is quite fast (It is still slower than [[Bresenham's line algorithm|Bresenham's]], though. The basis of the algorithm is to draw pairs of pixels straddling the line, coloured according to proximity. Pixels at the line ends are handled separately. Lines less than one pixel long should be handled as a special case.
 
Here is [[pseudocode]] for the nearly-horizontal case (<math>\deltaDelta x > \deltaDelta y</math>). The extension to cover nearly-vertical lines is trivial, and left as an exercise for the reader.
 
{{wikicode}}
<code>
'''function''' plot(x, y, c) {
plot the pixel at (x, y) with brightness c ''// where <math>0<= &le; c<= &le; 1</math>''
'''function''' ipart(x) {
}
'''function''' ipart(x) {
'''return''' ''integer part of x''
'''function''' round(x) {
}
'''function''' round(x) {
'''return''' ipart(x + 0.5)
'''function''' fpart(x) {
}
'''function''' fpart(x) {
'''return''' ''fractional part of x''
'''function''' rfpart(x) {
}
'''function''' rfpart(x) {
'''return''' 1 - fpart(x)
''// check that x<sub>1</sub>x1 < x<sub>2</sub>x2''
}
'''if x2 < x1
''// check that x<sub>1</sub> < x<sub>2</sub>''
swap x1, x2
'''if x<sub>2</sub> < x<sub>1</sub>
dx = x2 - x1
swap x<sub>1</sub>, x<sub>2</sub>
dy = y2 - y1
dx = x<sub>2</sub> - x<sub>1</sub>
dy = y<sub>2</sub> - y<sub>1</sub>
gradient = dy / dx
 
''// handle first endpoint''
xend = round(x<sub>1</sub>x1)
yend = y<sub>1</sub>y1 + gradient * (xend - x<sub>1</sub>x1)
xgap = rfpart(x<sub>1</sub>x1 + 0.5)
xpxl1 = xend '' // this will be used in the main loop''
ypxl1 = ipart(yend)
brightness1plot(xpxl1, =ypxl1, rfpart(yend) * xgap)
brightness2plot(xpxl1, =ypxl1 + 1, fpart(yend) * xgap)
intery = yend + gradient ''// first y-intersection for laterthe main loop''
plot(xpxl1, ypxl1, brightness1)
 
plot(xpxl1, ypxl1+1, brightness2)
intery = yend + gradient ''// first y-intersection for later''
''// handle second endpoint''
xend = round(x<sub>2</sub>x2)
yend = y<sub>2</sub>y2 + gradient * (xend - x<sub>2</sub>x2)
xgap = rfpart(x<sub>2</sub>x2 - 0.5)
xpxl2 = xend '' // this will be used in the main loop''
ypxl2 = ipart(yend)
brightness1plot(xpxl2, =ypxl2, rfpart(yend) * xgap)
brightness2plot(xpxl2, =ypxl2 + 1, fpart(yend) * xgap)
 
plot(xpxl2, ypxl2, brightness1)
''// main loop''
plot(xpxl2, ypxl2+1, brightness2)
'''for''' x '''from''' xpxl1 + 1 '''to''' xpxl2 - 1 {
brightness1plot(x, =ipart(intery), rfpart(intery))
brightness2plot(x, ipart(intery) + =1, fpart(intery))
plot(x, ipart(intery), brightness1)
plot(x, ipart(intery)+1, brightness2)
intery = intery + gradient
}
Line 66 ⟶ 60:
==External links==
* [http://www.ece.mcmaster.ca/~xwu/ Xiaolin Wu's homepage]
 
{{comp-stub}}
 
[[Category:Geometric algorithms]]