在空白图像上绘制两个点,坐标分别为(24,26)和(140,624),并且绘制出以该点为端点的直线。要求利用DDA、中点直线及Bresenham算法进行绘制。
使用DDA、中点画线和Bresenham画线法绘制直线,将其作为函数加载运行
#画线
from PIL import Image
def DDA(x1, y1, x2, y2):#DDA画线法
g = Image.new('RGB', (650, 650), color='white')#设置背景
dx = x2 - x1#计算两点间的横坐标距离
dy = y2 - y1#计算两点间纵坐标距离
e = abs(dx) if (abs(dx) > abs(dy)) else abs(dy) #计算两个距离哪个大,用大的画小的
dx /= e#计算每次画点时的增量
dy /= e#同上
x = x1#给初始点复制
y = y1#同上
i = 0
while i <= e:#循环画点
g.putpixel((int(x + 0.5), int(y + 0.5)), 0)#四舍五入
x+=dx#x增加 dx=1
y+=dy#y增加 dy=(dx)*(y2-y1)/(x2-x1) 其中dx=1
i+=1
g.show()
def middle(x1,y1,x2,y2):#中点画线法
g=Image.new('RGB',(650,650),(255,255,255))#设置白色背景
key=0
if abs(x1-x2)>abs(y1-y2):#判断用x画y还是用y画x
x1,x2,y1,y2=y1,y2,x1,x2
key=1
#以y画x的形式,当x距离大于y时,x,y位置互换(上一步已操作)
#ax+by+c=0
a=y2-y1#方程中a
b=x1-x2#方程中b
d=2*b+a#决策参数初始值
delta1=2*b#初始化
delta2=a+a+b+b
x=x1#开始点位置
y=y1
g.putpixel((x,y),0)#画点
while y<y2:#终止条件,用y画x
#如果决策变量<0,在右上角画点,否则,在右侧画点
if d<0:
x+=1
y+=1
d+=delta2#更新决策变量
else:
y+=1
d+=delta1
if key==1:
xg,yg=y,x
else:
xg,yg=x,y
g.putpixel((xg,yg),0)
g.show()
def Bresenham(x1,y1,x2,y2):#Bresenham画点法
g=Image.new('RGB',(650,650),color='white')#建立空白图片
key=0
if abs(x1-x2)<abs(y1-y2):#判断用x画y还是用y画x
x1,x2,y1,y2=y1,y2,x1,x2
key=1
#以y画x的形式,当x距离大于y时,x,y位置互换(上一步已操作)
x=x1#起始点初始化
y=y1#同上
dx=x2-x1#计算起始点、终止点的距离
dy=y2-y1#同上
p=2*dy-dx#决策变量
while x<=x2:#循环画点,直到画到终点
if key==1:
xg,yg=y,x
g.putpixel((xg,yg),0)
if p>=0:#如果决策变量>=0,画点在右上角
y+=1
p+=dy+dy-dx-dx#更新决策变量
else:#否则,在右侧画点
p+=dy+dy#更新决策变量
x+=1#每次以横坐标向右移动一个单位
g.show()
DDA(24,26,140,624)
middle(24,26,140,625)
Bresenham(24,26,140,624)
像素是不可分割的最小画图单元,所以在绘制图像时,有时遇到需要非整数的像素,急需要近似取整数。但是如何取整是一门技术。这里的三种画线方法讲述如何近似取点,使图像还可以正常的显现出来。