一个防止直线走样的函数

最近一直陷于绘图过程中直线走样的痛苦中,偶然从网上看到一个防止直线走样的函数,拿来试了下,效果还成。

在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;  
  }  
   }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值