我们知道,在VC里画直线时,如果该直线具有一定的倾斜度,那么直线会产生走样(锯齿),这要关系到光栅显示器的显示原理,具体怎么会发生走样我就不具体论述了,每本计算机图形学的书都有描述。下面提供一个画直线的算法函数,该算法具体作者不记得是谁了,我作了一些小的修改,在此提供,希望能对各位带来方便(你无须苦苦的另去研究一个算法啦^_^),直接拿去用即可。
void CSdiView::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;
}
}
}
// blend a pixel with the current colour and a specified colour
void CSdiView::AlphaBlendPixel(CDC* pDC, int x, int y,BYTE R, BYTE G, BYTE B,double ratio)
{
double minus_ratio;
int color_old;
BYTE R1, G1, B1;
BYTE R2, G2, B2;
//if((x < 0) || (x >=m_iWidth) || (y < 0) || (y >= m_iHeight)) //判断点是否在客户区内
// return;
color_old = pDC->GetPixel(x, y);
R1 = color_old & 0x0000FF;
G1 = (color_old & 0x00FF00) >> 8;
B1 = (color_old & 0xFF0000) >> 16;
minus_ratio = 1 - ratio;
B2 = (int)(B*ratio + B1*minus_ratio);
G2 = (int)(G*ratio + G1*minus_ratio);
R2 = (int)(R*ratio + R1*minus_ratio);
pDC->SetPixel(x, y, RGB(R2,G2, B2));
}
使用方法:
void CSdiView::OnDraw(CDC* pDC)
{
//CSdiDoc* pDoc = GetDocument();
//ASSERT_VALID(pDoc);
WuLine(pDC,CPoint(100,300),CPoint(321,60),RGB(255,0,0));
// pDC->MoveTo(100,300);
// pDC->LineTo(321,60);
}