Reputation: 65
I wrote a line drawing algorithm using the wu technique. It works but has issues. See below.
What I'm wondering is if anyone has tackled the problem of drawing anti-aliased lines? Suprisingly, a google search results in no satisfactory algorithms. Lots of discusions, but not a single complete, robust algorithm, independent of any dependencies on a graphics library.
If anyone wants sample code for the following function let me know. I'm hoping to replace this with a more robust function, but I have not found one yet. I'm sure that my algorithm can be improved, but it works.
struct xya { int x; int y; uint8_t a; xya(int x=0, int y=0, uint8_t a=0) : x(x), y(y), a(a) {} }; inline void wuline(xya*& out, int x0, int y0, int x1, int y1) { short DeltaX, DeltaY, XDir; static const int intensity = 8; if (y0 > y1) { short Temp = y0; y0 = y1; y1 = Temp; Temp = x0; x0 = x1; x1 = Temp; } *out++ = xya(x0,y0,255); if ((DeltaX = x1 - x0) >= 0) { XDir = 1; } else { XDir = -1; DeltaX = -DeltaX; } if ((DeltaY = y1 - y0) == 0) { while (DeltaX-- != 0) { x0 += XDir; *out++ = xya(x0,y0,255); } return; } if (DeltaX == 0) { do { y0++; *out++ = xya(x0,y0,255); } while (--DeltaY != 0); return; } if (DeltaX == DeltaY) { do { x0 += XDir; y0++; *out++ = xya(x0,y0,255); } while (--DeltaY != 0); return; } if (DeltaY > DeltaX) { unsigned short ErrorAcc = 0; unsigned short ErrorAdj = ((unsigned long) DeltaX > intensity; *out++ = xya(x0,y0,Weighting ^ 255); *out++ = xya(x0+XDir,y0,Weighting); } *out++ = xya(x1,y1,255); } else { unsigned short ErrorAcc = 0; unsigned short ErrorAdj = ((unsigned long) DeltaY > intensity; *out++ = xya(x0,y0,Weighting ^ 255); *out++ = xya(x0,y0+1,Weighting); } *out++ = xya(x1,y1,255); } }
Upvotes: 3
Views: 3975
Reputation: 7937
I was once given the task of drawing all sorts of complex and overlapping shapes that needed anti-aliasing. My solution was to draw everything to memory at a higher resolution (2x? 3x?) than the image that needed to be displayed. Then as a last step convert the high res image to low res by averaging the R,G and B separately for each of the multiple pixels in the high res version that would be reduced to a single pixel in the display image.
It may not be the most efficient way of doing things, but its dead easy to code and the visual effect was excellent.
Upvotes: 0
Reputation: 3285
Just curious why aren't you using a library to do this for you? For example on windows GDI+ supports antialiasing, and I'm sure that there is probably an implementation for QT & WX. Aside from those options, OpenGL would do the trick too.
GDI+ docs on anti-aliasing http://msdn.microsoft.com/en-us/library/ms535723%28VS.85%29.aspx
If you are doing it for the heck of it or academic, then just ignore me..
Upvotes: 1
Reputation: 311516
The canonical example for drawing antialiased lines quickly and efficiently is Xiaolin Wu's algorithm. You may want to look at that for a solid approach. Here's some sample code, too. The result of applying Wu's algorithm is on the right:
alt text http://www.suchit-tiwari.org/writings/antialias/antialias.png
Upvotes: 3