Python matplotlib 实现DDA算法

Python matplotlib 实现DDA算法

DDA算法全称数值微分法(Digital Differential Analyzer),是用数值方法解微分方程,即通过对x和y各增加一个小量,计算下一步的x、y值。实际上,应该令一个值增加1个单位,同时保证另一个值的增加量小于1个单位,这样才能绘制出更多的像素点,从而得到更准确的直线。因此,选择x增1还是y增1要看直线的斜率,
不妨令直线的表达式为:

y = k x + b y = kx + b y=kx+b
对于第i和第i+1个像素点,令x值分别为xi,xi+1,有
y i = k x i + b y_i = kx_i + b yi=kxi+b
y i + 1 = k x i + 1 + b y_{i+1} = kx_{i+1} + b yi+1=kxi+1+b
以上两式作差,可以得到:
Δ y = y i + 1 − y i = k ( x x + 1 − x i ) = k Δ x \Delta y = y_{i+1}-y_i=k(x_{x+1}-x_i)=k\Delta x Δy=yi+1yi=k(xx+1xi)=kΔx
由此可知,当x增加1个单位时,y增加k个单位;当y增加1个单位时,x增加 1/k 个单位。
因为要保证令一个值增加1个单位的同时,另一个值的增加量小于1个单位,所以当直线斜率k<1时,令x增1,y增k;当k>1时,令y增1,x增加 1/k;(k = 1时,两种情况都可以,默认x增1)

以下只考虑k<=1的情况。
直线的起点坐标为(x0,y0),下一个像素点的坐标(x1,y1),因为k<=1,所以
x 1 = x 0 + 1 , y 1 = y 0 + k x_1 = x_0 + 1,y_1=y_0+k x1=x0+1,y1=y0+k
因为像素点的坐标必须为整数,所以要对y1进行四舍五入处理,即Round(y1),Round()函数为自定义的四舍五入函数,这样做的含义是选择最接近(x1,y1)的像素点。
然后计算x2,y2,绘制(x2,Round(y2)),其中
x 2 = x 1 + 1 , y 2 = y 1 + k x_2=x1+1,y_2=y_1+k x2=x1+1,y2=y1+k
依次计算x3,y3,x4,y4…直到终点xn,yn。像素点集合(xi,Round(yi))即为组成直线的像素点,其中0<=i<=n。

代码部分:

函数介绍:

def Round(x):
    if  x >= 0:
        return int(x+0.5)
    else:
        return int(x-0.5)

四舍五入取整函数,注意与python自带的取整函数round()不同。

def ShowPoint(x,y):
    plt.plot(x,y,'*')
    plt.text(x,y,'(' + str(x) + ',' + str(y) + ')',fontsize = 14)
    return

显示函数,作用是显示像素点,并在对应位置标注(x,y)。

以下为主体代码:

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
plt.grid(True)
x=[]
y=[]
Input()
if  x[0]==x[1]:
    #斜率不存在时
    yi = min(y)
    for i in range(max(y) - min(y) + 1):
        ShowPoint(x[0],yi)
        yi = yi + 1
else:
    k = (y[1]-y[0])/(x[1]-x[0])
    if  abs(k)<=1:
        #k的正负无所谓
        xi = min(x)
        yi = min(y) if k>=0 else max(y)
        #k>=0时,直线递增,当x最小时,y最小
        #k<0时,直线递减,当x最小时, y最大
        for i in range(max(x)-min(x) + 1):
            ShowPoint(xi, Round(yi))
            xi = xi + 1#x增1
            yi = yi + k#y增k
    else:
        #abs(k)大于1的情况
        t = 1 / k
        yi = min(y)
        xi = min(x) if k>0 else max(x)
        for i in range(max(y) - min(y) + 1):
            ShowPoint(Round(xi),yi)
            xi = xi + t
            yi = yi + 1
plt.show()

缺点:
在DDA算法中,x(或y)和k必须用浮点数表示,这不便于用硬件实现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值