数值微分法( D D A DDA DDA)
一、原理
-
假定直线的起点、终点分别为: ( x 0 , y 0 ) (x_0,y_0) (x0,y0), ( x 1 , y 1 ) (x_1,y_1) (x1,y1),且都为整数。
则过端点 P 0 ( x 0 , y 0 ) P_0 (x_0, y_0) P0(x0,y0), P 1 ( x 1 , y 1 ) P_1(x_1, y_1) P1(x1,y1)的直线段 L : y = k x + b L:y=kx+b L:y=kx+b,直线斜率为:
k = y 1 − y 0 x 1 − x 0 ( x 1 ≠ x 0 ) k=\frac{y_1-y_0}{x_1-x_0}\ (x_1\neq x_0) k=x1−x0y1−y0 (x1=x0) -
假设 x x x已知,即从 x x x的起 x 0 x_0 x0开始,沿 x x x方向前进一个像素(步长= 1),可以计算出相应的y值。因为像素的坐标是整数,所以y值还要进行取整处理:
y = r o u n d ( y ) y=round(y) y=round(y) -
D D A DDA DDA算法就是一个增量算法,即在一个迭代算法中,如果每一步的 x x x、 y y y值是用前一步的值加上一个增量来获得,则称为增量算法。
-
这种方法直观,但效率太低,因为每一步需要一次浮点乘法和一次舍入运算。
二、计算
y i + 1 = k x i + 1 + b = k ( x i + Δ x ) + b = k x i + b + Δ x = y i + k Δ x \begin{aligned} y_{i+1} &= kx_{i+1}+b \\ &=k(x_i+\Delta x)+b\\ &=kx_i+b+\Delta x\\ &= y_i+k\Delta x\\ \end{aligned} \\ yi+1=kxi+1+b=k(xi+Δx)+b=kxi+b+Δx=yi+kΔx
- 当 x x x每递增 1 1 1, y y y递增 k k k(即直线斜率),即当 x i + 1 = x i + 1 x_{i+1}=x_i+1 xi+1=xi+1时, y i + 1 = y i + k y_{i+1}=y_i+k yi+1=yi+k;
- 取整: y i + 1 = r o u n d ( y i + k + 0.5 ) y_{i+1}= round(y_i+k+0.5) yi+1=round(yi+k+0.5);
- 注意上述分析的算法仅适用于 ∣ k ∣ ≤ 1 |k|≤1 ∣k∣≤1的情形。在这种情况下, x x x每增加 1 1 1, y y y最多增加 1 1 1。
- 当 ∣ k ∣ ≥ 1 |k|\geq 1 ∣k∣≥1时, y y y每增加 1 1 1, x x x增加 1 k \frac{1}{k} k1,之后同理。
三、举例
写出下列直线段 P 0 ( 0 , 0 ) → P 1 ( 5 , 2 ) P_0(0,0)\to P_1(5,2) P0(0,0)→P1(5,2)所经过实际坐标。
- 判断
k
k
k值,决定使用谁为增量
k = 2 − 0 5 − 0 = 0.4 < 1 k=\frac{2-0}{5-0}=0.4<1 k=5−02−0=0.4<1,使用 x x x为增量,步长为 1 1 1。 - 计算
x i + 1 = x i + 1 y i + 1 = y i + 0.4 \begin{aligned} x_{i+1}&=x_i+1\\ y_{i+1}&=y_i+0.4 \end{aligned} xi+1yi+1=xi+1=yi+0.4
即:当 x i + 1 = x i + 1 x_{i+1}=x_i+1 xi+1=xi+1时, y i + 1 = y i + 0.4 y_{i+1}=y_i+0.4 yi+1=yi+0.4
x | y+0.5 | int(y+0.5) |
---|---|---|
0 | 0+0.5 | 0 |
1 | 0.4+0.5 | 0 |
2 | 0.8+0.5 | 1 |
3 | 1.2+0.5 | 1 |
4 | 1.6+0.5 | 2 |
5 | 2.0+0.5 | 2 |
- 结果
经过如下5个坐标:
P 0 ( 0 , 0 ) 、 P 1 ( 1 , 0 ) 、 P 2 ( 2 , 1 ) 、 P 3 ( 3 , 1 ) 、 P 4 ( 4 , 2 ) 、 P 5 ( 5 , 2 ) P_0(0,0)、P_1(1,0)、P_2(2,1)、P_3(3,1)、P_4(4,2)、P_5(5,2) P0(0,0)、P1(1,0)、P2(2,1)、P3(3,1)、P4(4,2)、P5(5,2)