一个可以防止直线走样的画线函数(转)

我们知道,在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);
}

转载于:https://www.cnblogs.com/zhuchao/archive/2010/06/21/1761902.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值