算法目的:画一条直线
算法思想:
判断两个像素点的重点是在直线的下方,上方还是直线上,从而确定该选择那一个像素点。
线内: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;
好的,我们想在思路应该是更清晰一步了,我们只需对各个分类进行处理就好了
转http://blog.csdn.net/Joe_IceWind/article/details/4631475