最近一直陷於繪圖過程中直線走樣的痛苦中,偶然從網上看到一個防止直線走樣的函數,拿來試了下,效果還成。
在Windows裏畫直線時,如果該直線具有一定的傾斜度,那麼直線會產生走樣(鋸齒),這要關係到光柵顯示器的顯示原理,至於具體怎麼會發生走樣,原因過於複雜微妙,每本計算機圖形學的書都有描述。下面是從網上找到的一個畫直線的算法函數,該算法具體作者不記得是誰了,我作了一些小的修改,在此提供,希望能對各位帶來方便(你無須苦苦的另去研究一個算法啦),直接拿去用即可。
這個函數優點是:對於鋸齒的修正比較逼真,使用簡單方便,直接調用即可。
同時也有缺點:函數運算量有點大,對於速度要求比較高的程序不是很好。在多線程實時通信的程序中,要求界面實時刷新,運算量太大會直接導致圖形的刷新會出現閃爍(儘管不是很明顯)。不過對於閃爍的解決也很簡單——將繪製工作放入兼容DC中,利用二次緩存來顯示就可以了。不過,如果你的繪製工作是在一張位圖上,那麼閃爍情況就不太好解決了(至少我還沒有好的辦法)。在實時通信中,這有可能會導致你的程序跟老年癡呆一樣反應緩慢。由於我的程序是放在Windows CE系統上,至於在PC上會不會出現這種情況,還有待查證(我也懶的查證)。
代碼如下:
WuLine(CDC *pDC, CPoint &pt1, CPoint &pt2, int color)
{
int deltax, deltay, start, finish;
double dx, dy, dydx; // fractional parts
BYTE LR, LG, LB;
int x1,x2,y1,y2;
double d1,d2;
x1 = pt1.x; y1 = pt1.y;
x2 = pt2.x; y2 = pt2.y;
deltax = abs(x2 -x1); // Calculate deltax and deltay for initialisation
deltay = abs(y2 -y1);
if((deltax == 0)||(deltay == 0))
{
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
return;
}
LR =color&0x0000FF;
LG =(color&0x00FF00)>>8;
LB =(color&0xFF0000)>>16;
if(deltax > deltay) // then begin // horizontal or vertical
{
if(y2 > y1) // determine rise and run
dydx= -((double)deltay / deltax);
else
dydx = (double)deltay / deltax;
if(x2 < x1)
{
start = x2; // right to left
finish = x1;
dy = y2;
}
else
{
start = x1; // left to right
finish = x2;
dy = y1;
dydx = -dydx; // inverse slope
}
for(int x= start; x <= finish; x++)
{
d2 = modf(dy, &d1);
AlphaBlendPixel(pDC,x,(int)d1,LR,LG,LB,1-d2);
AlphaBlendPixel(pDC,x,(int)d1+1,LR,LG,LB,d2);
dy = dy + dydx; // next point
}
}
else
{
if(x2 > x1) // determine rise and run
dydx = -((double)deltax/deltay);
else
dydx = (double)deltax/deltay;
if(y2 < y1)
{
start = y2; // right to left
finish = y1;
dx = x2;
}
else
{
start = y1; // left to right
finish = y2;
dx = x1;
dydx = -dydx; // inverse slope
}
for(int y = start; y <= finish; y++)
{
d2 = modf(dx, &d1);
AlphaBlendPixel(pDC, (int)d1, y, LR, LG, LB, 1 - d2);
AlphaBlendPixel(pDC, (int)d1 + 1, y, LR, LG, LB, d2);
dx = dx + dydx;
}
}
}
一個防止直線走樣的函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.