Bresenham 画线算法:
与DDA算法相似,Bresenham画线算法也要在每列象素中找到与理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方向递增一个单位。另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。这一距离称为误差。算法的巧妙构思,使每次只需检查误差项(增量)的符号即可。
这里讨论直线斜率在(0,1)区间的情况,其他情况可以此类推。
定义决策变量:d =d+k (0<k<1) (k为直线斜率)
设0<k<1,如直线上的一点为(x,y),则下一点为:(x+1,y) (d<0.5) 或(x+1,y+1)(d>=0.5)
当d>1时,让d=d-1,以保证0<=d<1,d0=0
令e =d-0.5 (0<k<1),则e0 = -0.5
则下一点为:
(x+1,y),(e<0)
(x+1,y+1)(e>=0)
当e >0时, 让e =e-1,(重新初始化误差项)
核心代码:
from PySide2.QtCore import *
class Line:
def __init__(self, p):
self.p = p
def points_list_bresenhm(self):
points = []
if self.p[0].y() == self.p[1].y():
if self.p[0].x() > self.p[1].x():
self.p.reverse()
x = self.p[0].x()
y = self.p[0].y()
while x < self.p[1].x():
points.append(QPoint(x, y))
x = x+1
return points
if self.p[0].x() == self.p[1].x():
if self.p[0].y() > self.p[1].y():
self.p.reverse()
x = self.p[0].x()
y = self.p[0].y()
while y < self.p[1].y():
points.append(QPoint(x, y))
y = y+1
return points
m = (self.p[1].y()-self.p[0].y())/(self.p[1].x()-self.p[0].x())
if m > 0 and m <= 1:
if self.p[0].x() > self.p[1].x():
self.p.reverse()
e = -0.5
x = self.p[0].x()
y = self.p[0].y()
while x < self.p[1].x():
points.append(QPoint(x, y))
e = e + m
if e > 0:
e = e - 1
y = y + 1
x = x + 1
elif m >= -1 and m < 0:
if self.p[0].x() > self.p[1].x():
self.p.reverse()
e = 0.5
x = self.p[0].x()
y = self.p[0].y()
while x < self.p[1].x():
points.append(QPoint(x, y))
e = e + m
if e < 0:
e = e + 1
y = y - 1
x = x + 1
elif m > 1:
if self.p[0].y() > self.p[1].y():
self.p.reverse()
e = -0.5
x = self.p[0].x()
y = self.p[0].y()
while y < self.p[1].y():
points.append(QPoint(x, y))
e = e + 1/m
if e > 0:
e = e - 1
x = x + 1
y = y + 1
else:
if self.p[0].y() > self.p[1].y():
self.p.reverse()
e = 0.5
x = self.p[0].x()
y = self.p[0].y()
while y < self.p[1].y():
points.append(QPoint(x, y))
e = e + 1 / m
if e < 0:
e = e + 1
x = x - 1
y = y + 1
return points
加上UI界面实现效果:
PS: 如需参考完整代码,请移步:https://download.csdn.net/download/qq_42185999/11834676 进行下载