最近一直陷于绘图过程中直线走样的痛苦中,偶然从网上看到一个防止直线走样的函数,拿来试了下,效果还成。
在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;
}
}
}
一个防止直线走样的函数
最新推荐文章于 2024-09-12 13:19:42 发布