python模拟Breaseman算法绘制直线
代码实现了任意斜率任意起点终点的绘制功能
重点是理解Breasenman算法的核心内容 根据di的状态来绘制i+1个点,并计算di+1
算法解释 给定两个点,计算出ed点在st点的哪个象限
其中第二象限是第一象限关于y轴对称
第四象限是第一象限关于x轴对称
第三象限直接交换st和ed即可
效果图
python不是很熟练,请无视我丑陋的代码风格
##python模拟Breaseman算法绘制直线
##代码实现了任意斜率任意起点终点的绘制功能
##重点是理解Breasenman算法的核心内容 根据di的状态来绘制i+1个点,并计算di+1
##算法解释 给定两个点,计算出ed点在st点的哪个象限
##其中第二象限是第一象限关于y轴对称
##第四象限是第一象限关于x轴对称
##第三象限直接交换st和ed即可
from pylab import *
##坐标轴增量
indexR=[0,0]
index=[0,0]
##默认斜率 y,x之间的差值
k=1
dy=1
dx=1
##用于查看di的列表
rdl=[]
##用于判断四个象限的情况
##一象限不用改变st ed
##二象限改变st和ed
def judgeLine(st,ed):
if(ed[0]==st[0] or ed[1]==st[1]):
return 1
def judgeSE(st,ed,index,indexR):
dy=ed[1]-st[1]
dx=ed[0]-st[0]
print(dx,dy)
## 一
if(dx>0 and dy>0):
indexR=[1,1]
index=[1,0]
## 三象限交换st和ed
elif(dy<0 and dx<0):
st,ed=ed,st
indexR=[1,1]
index=[1,0]
## 二象限 更改算法的方向,交换st和ed 即往右下角画
elif(dy>0 and dx<0):
## st,ed=ed,st
index=[-1,0]
indexR=[-1,1]
## 四象限 更改算法的方向
elif(dy<0 and dx>0):
index=[1,0]
indexR=[1,-1]
return st,ed,index,indexR
##不管哪个象限都要判断k大于1的情况,k大于1则改变绘点方式
def judgeK(index):
dy=ed[1]-st[1]
dx=ed[0]-st[0]
k=dy/dx
if(abs(k)>1):
##这里还要在加判断 如果是在一二象限 k大于1,则变为往上走
##如果是在三四象限 k大于1,则变为往下走
## index[0],index[1]=abs(index[1]),abs(index[0])
##1
if(dx>0 and dy>0):
index=[0,1]
##2
elif(dy>0 and dx<0):
index=[0,1]
##3
elif(dy<0 and dx<0):
index=[0,-1]
##4
elif(dy<0 and dx>0):
index=[0,-1]
dx,dy=dy,dx
return dx,dy,k,index
##计算点并加入到a中
def calPoint(dx,dy,a,rd):
tdx=abs(dx)
tdy=abs(dy)
for i in range(0,abs(dx)):
if rd>=0:
tt=[a[i][0]+indexR[0],a[i][1]+indexR[1]]
a.append(tt)
rd=rd+2*(tdy-tdx)
else:
tt=[a[i][0]+index[0],a[i][1]+index[1]]
a.append(tt)
rd=rd+2*tdy
rdl.append(rd)
##根据a中的前后两点绘制线
def drawLine(a):
for i in range(len(a)):
plt.scatter(a[i][0],a[i][1],color='b')
for i in range(len(a)-1):
t1=[a[i][0],a[i+1][0]]
t2=[a[i][1],a[i+1][1]]
#plt.plot(t1,t2,'r');
##设置坐标系信息
def setAxis(st,ed):
lent=range(-15,15,1)
plt.xticks(lent)
plt.yticks(lent)
plt.plot([-18,18],[0,0],'k')
plt.plot([0,0],[-18,18],'k')
plt.plot([st[0],ed[0]],[st[1],ed[1]],'y')
##绘制平行线
def drawVline(x,y,s0,mode):
if(x>y):x,y=y,x
for i in range(x,y):
if(mode==1):
plt.scatter(s0,i,color='b')
elif(mode==0):
plt.scatter(i,s0,color='b')
st=list(map(int,input("起点:").split()))
ed=list(map(int,input("终点:").split()))
setAxis(st,ed)
##在这里特判直线平行坐标轴的情况
if(judgeLine(st,ed)):
t1=[st[0],ed[0]]
t2=[st[1],ed[1]]
plt.plot(t1,t2,'y')
plt.scatter(st[0],st[1],color='b')
plt.scatter(ed[0],ed[1],color='b')
if(st[0]==ed[0]):
drawVline(st[1],ed[1],st[0],1)
else:
drawVline(st[0],ed[0],st[1],0)
plt.show()
else:
st,ed,index,indexR=judgeSE(st,ed,index,indexR)
dx,dy,k,index=judgeK(index)
rd=2*abs(dy)-abs(dx)
a=[st]
calPoint(dx,dy,a,rd)
drawLine(a)
plt.show()