图形学--(中点画线法+Bresenham画线算法)

Posted 浮生缘,半生梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形学--(中点画线法+Bresenham画线算法)相关的知识,希望对你有一定的参考价值。

   

     编程环境:codeblocks+EGE库

     用到的函数:putpixel(int x1,int y1,int color)  用某种颜色打亮一个坐标点。

 这俩种算法都是用来在计算机上画一条直线的,那么我们为什么不直接用直线方程分别带点再打亮呢,这是因为,计算机中每个坐标点都是整数,而直线是由一个个像素点组合而成的,那么,直接将坐标点再进行四舍五入整数化就好了啊,的确,这是一种方法,但计算机中进行浮点数的四舍五入会使运算效率变差,因此真正画直线时是用到上边这俩种方法的。

1、中点画线法

  只考虑当直线的斜率|k|<1时的情况,假设现在有一条直线(x1,y1,x2,y2),那么第一个点一定是(x1,y1)无疑,下一个点的x坐标为x1+1,y坐标要么为y1要么为y1+。关键在于每次取下一个点时,是取前一个的y1呢,还是y1+1,这时一定是取直线上点最靠近的那个了,而判断取哪个点就用到了中点,我们将中点代入直线中 d=F(x1+1,y1+0.5)=a*(x1+1)+b*(y1+0.5)+c。

    (1)如果直线d>=0,则取下边的点也就是(x1+1,y1)。 (2)如果直线d<0,则取上边的点也就是(x1+1,y1+1)。

  它的实际过程就是这样每次根据前边的点判断下一个点在哪,然后进行打亮,但这样每次判断的时候都得代入直线方程计算太麻烦了,我们将这俩种情况分别代入直线方程中可以找出规律:

    (1)当直线>=0时,经过化解得d1=d+a;

   (2)当直线<0时,经过化解得d2=d+a+b;

    (3)初始值d0=a+0.5b。

也就是说每次的增量要么为a,要么为a+b,那么这样判断的时候就简单多了,因为我们每次只是判断它的正负。所以给等式同时乘2,将其中浮点数0.5化为整数,这样硬件操作时无疑更快了。

代码:

 1 #include <iostream>
 2 #include <graphics.h>
 3 using namespace std;
 4 //中点画线法
 5 void line1(int x1,int y1,int x2,int y2){
 6 
 7      int x,y,d0,d1,d2,a,b;
 8      y=y1;             
 9      a=y1-y2;          //直线方程中的a的算法
10      b=x2-x1;          //直线方程中的b的算法
11      d0=2*a+b;         //增量初始值
12      d1=2*a;           //当>=0时的增量
13      d2=2*(a+b);       //当<0时的增量
14      for(x=x1;x<=x2;x++){
15             putpixel(x,y,GREEN);   //打亮
16         if(d0<0){
17             y++;            
18             d0+=d2;
19         }else{
20 
21         d0+=d1;
22         }
23 
24      }
25 }
26 //Bresenham画线算法
27 void line2(int x1,int y1,int x2,int y2){
28 
29    int x,y,dx,dy,d;
30    y=y1;               
31    dx=x2-x1;         
32    dy=y2-y1;     
33    d=2*dy-dx;        //增量d的初始值
34    for(x=x1;x<=x2;x++){
35     putpixel(x,y,GREEN);   //打亮
36     if(d<0){
37         d+=2*dy;
38     }else{
39       y++;
40       d+=2*dy-2*dx;
41     }
42 
43 
44 
45    }
46 
47 }
48 int main()
49 {
50     initgraph(640,480);       //打开EGE初始化
51     line1(200,160,400,400);   //画线
52     getch();                  //等待用户操作
53     closegraph();             //关闭图形
54     return 0;
55 }

2、Bresenham画线算法

  这种画线算法的思想和中点画线的一致,只是在判断取哪个点时,不是看它位于中点的上边还是下边,而是将这俩个点到直线上那个点的距离相减,判断其正负,如果下边的点到直线实际点距离远则的d1-d2>=0那么取上边的点y1+1,同样也是代入直线化解可以得出下面结论:

  (1)当d1-d2<0时,d=d+2*dy.

  (2)当d1-d2>=0时,d=d+2*dy-2*dx.

  (3)d的初始值为  d=2*dy-dx.

 其代码如上所示。运行截图如下:

 

以上是关于图形学--(中点画线法+Bresenham画线算法)的主要内容,如果未能解决你的问题,请参考以下文章

用C++如何实现bresenham画线算法?计算机图形学上面有个drawpixel的函数。不知道怎么用。

Bresenham画线算法

计算机图形学中的中点画线,中点画圆,Bresenham画线与画圆算法

计算机图形学 - 直线的扫描转换算法

计算机图形学 - 直线的扫描转换算法

求计算机图形学中的直线绘制函数法、DDA算法、中点法和Bresenham算法的优缺点以及比较.