中点画线法

算法目的:画一条直线

算法思想:

判断两个像素点的重点是在直线的下方,上方还是直线上,从而确定该选择那一个像素点。

线内:F(x,y) ==0;

上方:F(x,y) > 0;

下方:F(x,y) < 0;

------------------------------------------------------------------------------------------------------------------------------------

证明:若是像素点在直线上,则肯定满足直线方程,则将像素点(x0,y0)带入方程得:

ax0 + by0 + c = 0;

由于直线下方的点在和直线上的点的x坐标相同时,其纵坐标小于直线上的点:

故ax0 + by + c  < 0;(y < y0);

同理:直线上方的点(x0,y),ax0 + by + c > 0; (y > y0);

-------------------------------------------------------------------------------------------------------------------------------------

寻找中点:

--------------------------------------------------------------------------------------------------------------------------------------

当|k| < 1 && k > 0时;

由于此时,横坐标的变化速度大于纵坐标,故此时我们以横坐标的变化为基准.

取直线上任意一点(xp,yp).这一点已确定作为直线上的一点,那么我们在确定一下点时,就应该寻找(xp+1,yp),(xp+1,yp+1)两个像素点的中点(xp+1,yp+0.5);并判断该点是处于直线的那个方向:

直线上:可以两点任意一点。

上方: 取(xp+1,yp);

下方: 取(xp+1,yp+1);

*************************

如何判断该点在直线的那个方向呢?

由上述表述可知:

线内:F(x,y) ==0;

上方:F(x,y) > 0;

下方:F(x,y) < 0;

故我们只需把该店带入方程,并判断方程的正负即可:

d0 = a(xp+1) + b(yp+0.5) + c

 --->  d0 = axp + byp + c + a + 0.5b;

若我们令: d = axp + byp + c;

则: d0 = d + a + 0.5b;

现在我们只需判断d0的正负即可判断点在直线的方向,从而就可以确定该选择点(xp+1,yp),还是点(xp+1,yp+1);

若d0 < 0;--->(xp+1,yp+1);

若d0 > 0;--->(xp+1,yp);

若d0==0;--->两者均可.

现在分别讨论下每种情况:

d0 < 0; ---->(xp+1,yp+1)

我们来算一下下个中点的值:

下一个中点应该为:(xp+2,yp+1.5);

d1 = a(xp+2) + b(yp+1.5) + c;

---> d1 = axp + byp + c + 2a + 1.5b;

---> d1 = axp + byp + c + a + 0.5b + a + b;

---> d1 = d0 + a + b;

我们可以看出当d0 < 0时,下一个中点的增量为 a+b.故我们可以通过增量计算下一个中点,而不用再通过坐标重新计算中点值了;

d0 > 0; ---> (xp+1,yp);

我们算下这种情况下的中点值:

下一个中点应该为:(xp+2,yp+0.5)

d2 = a(xp+2) + b(yp+0.5) + c;

---> d2 = axp + byp + c + 2a + 0.5b;

---> d2 = d + a + 0.5b + a;

---> d2 = d0 + a;

我们可以看出当d0 > 0时,下一个中点的增量为 a,故我们可以通过+a得到下一个中点值.

当d0 == 0;时,由于选择哪种情况都可以,故我们可以把它放入上面任意一种情况之中.

我们在看一下d0值.

d0 = d + a + 0.5b;

由于 d = axp + byp + c;

且点(xp,yp)在直线上,所以d == 0;所以我们判断d0的正负只需判断a + 0.5b的正负即可,而我们再求下一个中点的值来判断正负时,只需加上增量,来判断相加之后的值的正负即可.

---------------------------------------------------------------------------------------------------------------

|k| >= 1;时同理.

---------------------------------------------------------------------------------------------------------------

算法开始:

我们假设从(x0,y0)开始画直线:由于(x0,y0)在直线上.

故: ax0 + by0 + c = 0;

则d0 = a + 0.5b.由于我们使用的只是d的符号,而增量都是整数,故我们可以用2d来代替d来摆脱浮点数。

故 d = 2a + b; d1 = 2(a+b); d2 = 2a;

*******************************

我们该如何计算a,b的值呢?

下面我们将画线已知的两点(x0,y0),(x1,y1)带入直线方程:ax + by + c = 0;得:

a / b = y0 - y1/ x1 - x0;

现在我们将直线方程变形一下:

y = -a/b x - c/b;

由此可知,只要a/b c/b的值确定后,直线方程就确定了,a,b是何值无关紧要只要满足a/b的值即可.

故我们可以令:

a = y0 - y1; b = x1 - x0;

 算法思想基本上算是分析完成了。该开始写代码了。基本上都是思想容易,想转换为正确的代码就难了:为了写出正确的代码,我们现在理一下思路,我们应该把直线分为几种情况呢?

应该有四种情况:

因为直线的斜率绝对值是否大于1,以及直线的斜率是否大于0 都将会影响到我们的算法:

故我们这样分类:

① 0 < k < = 1

② k > 1

③ -1 < k <= 0

④ k <= -1;

好的,我们想在思路应该是更清晰一步了,我们只需对各个分类进行处理就好了。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Joe_IceWind/archive/2009/10/04/4631475.aspx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值