改进的 Bresenham 画线算法程序

原创 2007年10月13日 04:36:00
// By rappizit@yahoo.com.cn
// 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)(intintint))
{
    
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-2000, 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 (
00, x, y, RGB (000), drawpixel);
        }

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

运行结果(见下图):
http://p.blog.csdn.net/images/p_blog_csdn_net/rappy/339034/o_IntBresenhamline.jpg


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

Bresenham 算法详解

这篇文章讲的非常详细,这里列出几点注意事项 1、bresenham的起始点是整数点,所有初始的 error值 又 y1 来计算, 即 m - 0.5 2、当error值大于0时,取了上面的点,所以...
  • kakaxi2222
  • kakaxi2222
  • 2016年02月21日 16:37
  • 993

Bresenham画线算法C++

Bresenham画线算法C++ //斜率为0
  • HW140701
  • HW140701
  • 2016年11月18日 15:49
  • 1340

Bresenham 画直线算法

画线的算法不少,但要作到高速、简单并不容易。斜率相乘法是最简单的方法之一,但计算每个点均要花费不少时间用于乘、除法运算;下面介绍的是Bresenham's高效画线算法,对每个点的坐标计算只要加、减法就...
  • jiayichendddd
  • jiayichendddd
  • 2014年08月16日 14:32
  • 4605

计算机图形学(二)输出图元_3_画线算法_3_Bresenham画线算法

Bresenham画线算法是由Bresenham提出的一种精确而有效的光栅线生成算法,该算法仅仅使用增量整数计算。另外Bresenham算法还可用于显示圆和其他曲线。图3.8和图3.9给出了绘制线段的...
  • heyuchang666
  • heyuchang666
  • 2016年04月18日 15:12
  • 5083

用OPenGL实现 Bresenham画线算法

#include #include #include int xs,ys,xe,ye; void BresenhamLine(int x0,int y0,int x1,int y1) { if((x...
  • u012156133
  • u012156133
  • 2013年11月01日 20:21
  • 1879

图形学实验一:bresenham算法 画线和画圆

我编程环境用的是codeblock,所以我就在此基础上,做关于此实验的讲解。 首先,先要在codeblocks上配置opencv: http://blog.csdn.net/dupei/arti...
  • sunny_xsc1994
  • sunny_xsc1994
  • 2014年11月08日 14:34
  • 3791

Bresenham 算法详解

这篇文章讲的非常详细,这里列出几点注意事项 1、bresenham的起始点是整数点,所有初始的 error值 又 y1 来计算, 即 m - 0.5 2、当error值大于0时,取了上面的点,所以...
  • kakaxi2222
  • kakaxi2222
  • 2016年02月21日 16:37
  • 993

画线算法 - Bresenham原理及Java实现

布氏(Bresenham)是绘制线段最有效率的算法之一,该算法仅仅使用整型加减及字节位操作运算 (省去了用于计算斜率的除法运算),因而计算效率非常高。其实现也非常的简单明了。本文以Java代码为例,一...
  • jinbing_peng
  • jinbing_peng
  • 2015年04月01日 03:22
  • 2147

【OpenGL】直线生成算法DDA+Bresenham

OpenGL 直线生成算法 DDA + Bresenham
  • u012866328
  • u012866328
  • 2016年09月20日 22:20
  • 3083

图形学_画线算法(DDA、Bresenham)

1. DDA算法实现直线绘制(需先安装easyx,百度下载即可)   1 #include "easyx.h" 2 #include "math.h" 3 #include "win...
  • bcj296050240
  • bcj296050240
  • 2015年05月15日 16:29
  • 1239
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:改进的 Bresenham 画线算法程序
举报原因:
原因补充:

(最多只允许输入30个字)