Antialiasing - Wu Algorithm - CodeProject PDF
Antialiasing - Wu Algorithm - CodeProject PDF
Antialiasing:WuAlgorithmCodeProject
Antialiasing: Wu Algorithm
.Suchit, 6 Nov 2007
4.95 40 votes
Generating smooth lines with antialiasing; sample code for animation is included
Table of Contents
Introduction
Background
Using the Code
Demo: Spokes Animation
DrawWuLine Function
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
1/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
Resources
Credits
Introduction
Jagged lines are major obstacles in achieving professional displays of raster graphics.
Antialiasing can produce very smooth lines and provide a stylish appearance. You must already
have observed goodlooking antialiased diagrams in PowerPoint 2003. They look very smooth.
Although GDI+ offers antialiasing, most computers may not have its redistributable. With .NET,
you get antialiasing, but again, most computers may not have the .NET framework available. So I
prefer writing "Windows portable" programs in VC++ 6. Hence, here is an MFC version of the
Wu Antialiasing Algorithm.
Background
Research has led to the creation of several techniques for antialiasing. Graphics textbooks like
Foley, Van Dam discuss the GuptaSproul and related algorithms. For fast antialiasing, Xiaolin Wu
invented an algorithm called by his name: Wu Antialiasing. Michael Abrash's Graphics
Programming Black Book gives excellent treatment of this algorithm. Hugo Elias also has an
excellent article on the matter; I strongly recommend reading this one. However, neither have
MFCusable code, so I have implemented their code on MFC.
I wrote a simple WuCircle routine to generate a circle made up of line segments. Now let's see
difference that we achieve by using this implementation. Figure 2 shows the zoomed views of
the above spokes. The image on the left side shows normal drawing. The jagged edges are
clearly visible in it. The rightside image is the antialiased drawing and we can see the smoothing
achieved using "GrayScale" intensities.
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
2/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
There is a simple routine for circle generation, which you can reuse. Internally, it calls the line
routine explained above.
voidDrawWuCirlce(CDC*pDC,intx,inty,intr);
/*
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
3/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
Arguments:
+pDCiswherecircleisdrawn.Canbememorydevicecontext.
+(x,y)iscenterofcircle.
+risradiusofcircle.
*/
Both functions can be easily modified to use HDC instead of CDC*, in case you are writing non
MFC Win32 applications.
RotorThread is a routine that animates spooked wheels. It uses a memory bitmap and a device
context. At ~20 fps frames per second, it rotates the wheels on a memory bitmap. Using
BitBlt, the drawing is brought on the main window.
Pressing "a" again terminates the thread.
UINTRotorThread(LPVOIDlpVoid)
{
bool*pbStop=(bool*)lpVoid;
CWnd*pWnd=AfxGetMainWnd();
CDC*pDC=pWnd>GetDC();
CRectrect;
pWnd>GetClientRect(&rect);
CDCmemDC;
memDC.CreateCompatibleDC(pDC);
CBitmapbitmap;
bitmap.CreateCompatibleBitmap(pDC,
rect.Width(),rect.Height());
memDC.SelectObject(&bitmap);
CFontfont;
font.CreatePointFont(185,"Verdana",&memDC);
memDC.SelectObject(&font);
memDC.SetTextAlign(TA_CENTER);
floatphase=0.0f;
while(!(*pbStop))
{
//1.EraseBackground.
memDC.Rectangle(0,0,rect.Width(),rect.Height());
//2.Drawnewcontents.
memDC.TextOut(100,15,"Normal");
memDC.TextOut(350,15,"Antialiased");
shortx,y;
for(floattheta=phase;theta<
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
4/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
360+phase;theta+=10)
{
x=(short)(100.0*cos(theta*3.14/180.0)+355.0);
y=(short)(100.0*sin(theta*3.14/180.0)+155.0);
DrawWuLine(&memDC,x,y,355,155,0,256,8);
memDC.MoveTo(x240,y);
memDC.LineTo(115,155);
}
//3.Blitdrawingonscreen.
pDC>BitBlt(0,0,rect.Width(),rect.Height(),
&memDC,0,0,SRCCOPY);
//4.Updateanimationparameter.
phase+=1;
::Sleep(67);//15fps.
}
font.DeleteObject();
bitmap.DeleteObject();
memDC.DeleteDC();
pWnd>ReleaseDC(pDC);
return0;
}
DrawWuLine Function
Here is the implementation of the DrawWuLine function:
voidDrawWuLine(CDC*pDC,shortX0,shortY0,shortX1,shortY1,
shortBaseColor,shortNumLevels,unsignedshortIntensityBits)
{
unsignedshortIntensityShift,ErrorAdj,ErrorAcc;
unsignedshortErrorAccTemp,Weighting,WeightingComplementMask;
shortDeltaX,DeltaY,Temp,XDir;
/*Makesurethelinerunstoptobottom*/
if(Y0>Y1){
Temp=Y0;Y0=Y1;Y1=Temp;
Temp=X0;X0=X1;X1=Temp;
}
/*Drawtheinitialpixel,whichisalwaysexactlyintersectedby
thelineandsoneedsnoweighting*/
DrawPixel(pDC,X0,Y0,BaseColor);
if((DeltaX=X1X0)>=0){
XDir=1;
}else{
XDir=1;
DeltaX=DeltaX;/*makeDeltaXpositive*/
}
/*Specialcasehorizontal,vertical,anddiagonallines,which
requirenoweightingbecausetheygorightthroughthecenterof
everypixel*/
if((DeltaY=Y1Y0)==0){
/*Horizontalline*/
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
5/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
while(DeltaX!=0){
X0+=XDir;
DrawPixel(pDC,X0,Y0,BaseColor);
}
return;
}
if(DeltaX==0){
/*Verticalline*/
do{
Y0++;
DrawPixel(pDC,X0,Y0,BaseColor);
}while(DeltaY!=0);
return;
}
if(DeltaX==DeltaY){
/*Diagonalline*/
do{
X0+=XDir;
Y0++;
DrawPixel(pDC,X0,Y0,BaseColor);
}while(DeltaY!=0);
return;
}
/*Lineisnothorizontal,diagonal,orvertical*/
ErrorAcc=0;/*initializethelineerroraccumulatorto0*/
/*#ofbitsbywhichtoshiftErrorAcctogetintensitylevel*/
IntensityShift=16IntensityBits;
/*Maskusedtoflipallbitsinanintensityweighting,producingthe
result(1intensityweighting)*/
WeightingComplementMask=NumLevels1;
/*IsthisanXmajororYmajorline?*/
if(DeltaY>DeltaX){
/*Ymajorline;calculate16bitfixedpointfractionalpartofa
pixelthatXadvanceseachtimeYadvances1pixel,truncatingthe
resultsothatwewon'toverruntheendpointalongtheXaxis*/
ErrorAdj=((unsignedlong)DeltaX<<16)/(unsignedlong)DeltaY;
/*Drawallpixelsotherthanthefirstandlast*/
while(DeltaY){
ErrorAccTemp=ErrorAcc;/*remembercurrrentaccumulatederror*/
ErrorAcc+=ErrorAdj;/*calculateerrorfornextpixel*/
if(ErrorAcc<=ErrorAccTemp){
/*Theerroraccumulatorturnedover,soadvancetheXcoord*/
X0+=XDir;
}
Y0++;/*Ymajor,soalwaysadvanceY*/
/*TheIntensityBitsmostsignificantbitsofErrorAccgiveusthe
intensityweightingforthispixel,andthecomplementofthe
weightingforthepairedpixel*/
Weighting=ErrorAcc>>IntensityShift;
DrawPixel(pDC,X0,Y0,BaseColor+Weighting);
DrawPixel(pDC,X0+XDir,Y0,
BaseColor+(Weighting^WeightingComplementMask));
}
/*Drawthefinalpixel,whichis
alwaysexactlyintersectedbytheline
andsoneedsnoweighting*/
DrawPixel(pDC,X1,Y1,BaseColor);
return;
}
/*It'sanXmajorline;calculate16bitfixedpointfractionalpartofa
pixelthatYadvanceseachtimeXadvances1pixel,truncatingthe
resulttoavoidoverrunningtheendpointalongtheXaxis*/
ErrorAdj=((unsignedlong)DeltaY<<16)/(unsignedlong)DeltaX;
/*Drawallpixelsotherthanthefirstandlast*/
while(DeltaX){
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
6/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
ErrorAccTemp=ErrorAcc;/*remembercurrrentaccumulatederror*/
ErrorAcc+=ErrorAdj;/*calculateerrorfornextpixel*/
if(ErrorAcc<=ErrorAccTemp){
/*Theerroraccumulatorturnedover,soadvancetheYcoord*/
Y0++;
}
X0+=XDir;/*Xmajor,soalwaysadvanceX*/
/*TheIntensityBitsmostsignificantbitsofErrorAccgiveusthe
intensityweightingforthispixel,andthecomplementofthe
weightingforthepairedpixel*/
Weighting=ErrorAcc>>IntensityShift;
DrawPixel(pDC,X0,Y0,BaseColor+Weighting);
DrawPixel(pDC,X0,Y0+1,
BaseColor+(Weighting^WeightingComplementMask));
}
/*Drawthefinalpixel,whichisalwaysexactlyintersectedbytheline
andsoneedsnoweighting*/
DrawPixel(pDC,X1,Y1,BaseColor);
}
Resources
Good reference materials:
Michael Abrash's Graphics Programming Black Book.
Hugo Elias' Theory of Wu Lines.
Textbook: Computer Graphics by Foley, Van Dam et. al.
Credits
Eien posted a colored version of the algorithm that I had planned as the next installment, for
simplicity.
Thank you, Eien!
Updates
The entire code for this has been hosted at Google Code to enable Open Source development.
Please feel free to join that development group and contribute to it. At the moment, the FLTK
project is using this work.
Your comments and suggestions are always welcome. Just post here.
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
7/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
History
8 March 2006 Original version posted
10 March, 2006 Article moved
6 November, 2007 Article contents updated
License
This article has no explicit license attached to it but may contain usage terms in the article text or
the download files themselves. If in doubt please contact the author via the discussion board
below.
A list of licenses authors might use can be found here
Share
About the Author
.Suchit
Architect GE India Innovation Center
India
He architected and developed portions of Proficy RX, a Process Analytical Technology PAT
Solution of GE Fanuc Intelligent Platforms.
He also is the Architect of OPC Server for hardware devices of GE Sensing. These devices
sense temperature, humidity, combustibles, fluid flow, pressure and various engineering
parameters primarily used in Industrial Automation & Process Control applications.
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
8/9
26/1/2015
Antialiasing:WuAlgorithmCodeProject
He lives in Hyderabad India with his wife and 2 kidbots. Loves reading books if these 2 small
buddies allow him to.
Homepage : http://www.SuchitTiwari.Org
Seleccionar idioma
http://www.codeproject.com/Articles/13360/AntialiasingWuAlgorithm?display=Print
9/9