改进的 Bresenham 画线算法程序

//  By [email protected]
// 2007-10-15 第 2 版

#define  ABS(a) (a >= 0 ? a : -a)
#define  SWAP(a, b) {int t = a; a = b; b = t;}

//  改进的 Bresenham 画线算法程序
//  最后一个形参是画图函数 drawpixel (int x, int y, int color) 的指针,在不同运行环境下调用不同的画图函数
void  IntBresenhamline ( int  x0,  int  y0,  int  x1,  int  y1,  int  color,  void ( * drawpixel)( int int int ))
{
    
int  dx  =  x1  -  x0, dy  =  y1  -  y0;
    
if  (ABS(dx)  >=  ABS(dy))
        {
        
if  (x0  >  x1)
            {
            SWAP(x0, x1);
            SWAP(y0, y1);
            dx 
=   - dx;
            dy 
=   - dy;
            }
        
if  (dy  >=   0 )
            {
            
//  直线的倾斜角位于 [0, pi / 4]
             for  ( int  x  =  x0, y  =  y0, e  =   - dx; x  <=  x1; x  ++ )
                {
                (
* drawpixel) (x, y, color);
                e 
+=  dy  *   2 ;
                
if  (e  >=   0 )
                    {
                    y 
++ ;
                    e 
-=  dx  *   2 ;
                    }
                }
            }
        
else     {
            
//  直线的倾斜角位于 [-pi / 4, 0)
             for  ( int  x  =  x0, y  =  y0, e  =  dx; x  <=  x1; x  ++ )
                {
                (
* drawpixel) (x, y, color);
                e 
+=  dy  *   2 ;
                
if  (e  <=   0 )
                    {
                    y 
-- ;
                    e 
+=  dx  *   2 ;
                    }
                }
            }
        }
    
else     {
        
if  (y0  >  y1)
            {
            SWAP(x0, x1);
            SWAP(y0, y1);
            dx 
=   - dx;
            dy 
=   - dy;
            }
        
if  (dx  >=   0 )
            {
            
//  直线的倾斜角位于 (pi / 4, pi / 2]
             for  ( int  x  =  x0, y  =  y0, e  =   - dy; y  <=  y1; y  ++ )
                {
                (
* drawpixel) (x, y, color);
                e 
+=  dx  *   2 ;
                
if  (e  >=   0 )
                    {
                    x 
++ ;
                    e 
-=  dy  *   2 ;
                    }
                }
            }
        
else     {
            
//  直线的倾斜角位于 [-pi / 2, -pi / 4)
             for  ( int  x  =  x0, y  =  y0, e  =  dy; y  <=  y1; y  ++ )
                {
                (
* drawpixel) (x, y, color);
                e 
+=  dx  *   2 ;
                
if  (e  <=   0 )
                    {
                    x 
-- ;
                    e 
+=  dy  *   2 ;
                    }
                }
            }
        }
}

//  参考调用形式

void  drawpixel( int  x,  int  y,  int  color)
{
    
//  To Do ...
}

int  main ()
{
    IntBresenhamline (
- 10 - 0 - 40 - 200 0 , drawpixel);
    
return   0 ;
}

//  在 **View.cpp 里面添加 (** 代表工程名)

CDC
*  m_pDC;     //  当前画图所用的 CDC 指针

void  drawpixel( int  x,  int  y,  int  color)
{
    m_pDC
-> SetPixel (x, y, color);
}

void  CGraphicsView::OnDraw(CDC *  pDC)
{
    CGraphicsDoc
*  pDoc  =  GetDocument();
    ASSERT_VALID(pDoc);
    
if  ( ! pDoc)
        
return ;

    
//  TODO: 在此处为本机数据添加绘制代码
    m_pDC  =  pDC;
    
    
//  自定义映射模式,令画图区域的中点为坐标原点,水平向右为 X 轴正方向,竖直向上为 Y 轴正方向
    CRect rect;
    GetClientRect (rect);
    pDC
-> SetMapMode (MM_ANISOTROPIC);
    pDC
-> SetWindowExt (rect.right, rect.bottom);
    pDC
-> SetViewportExt (rect.right,  - rect.bottom);
    pDC
-> SetViewportOrg (rect.right  /   2 , rect.bottom  / 2 );

    
double  pi  =   3.1415 , r  =   200.0 ;
    
for  ( double  rad  =   0 ; rad  <  pi  *   2.0 ; rad  +=  pi  /   30.0 )
        {
        
int  x  =  ( int )(r  *  cos (rad));
        
int  y  =  ( int )(r  *  sin (rad));
        IntBresenhamline (
0 0 , x, y, RGB ( 0 0 0 ), drawpixel);
        }

    ReleaseDC(pDC);
    m_pDC 
=  NULL;
}
 
由于 SetPixel 函数不能直接转为 IntBresenhamline 函数所能调用的函数指针,所以需要增加一个
drawpixel 的中间函数,而为了不重复申请 DC ,则需要保存当前 DC 作为全局变量。

运行结果(见下图):
改进的 Bresenham 画线算法程序_第1张图片


PS:图片经过压缩,质量有所下降。
         工程文件可以在 这里下载。

你可能感兴趣的:(图形学)