算法描述:
将文件中点的坐标代入到三次Bezier曲线表达式,给定步长,在两条曲线上各取n个点,分别计算各点距离,若距离小于给定的精度值d_p则认为相交,若两个交点的x距离小于给定的精度值x_p则认为是一个点,不重复计入。
#求两个3次Bezier 曲线的交点
def Readf():#读取文件
ls = []
ls1 = []
ls2 = []
ls = open("Bezier.txt").readlines()
ls[0] = ls[0].strip('\n').split(',')
ls[1] = ls[1].split(',')
for i in range(0,4):
ls1.append((eval(ls[0][2*i]), eval(ls[0][2*i+1])))
ls2.append((eval(ls[1][2*i]), eval(ls[1][2*i+1])))
return ls1, ls2
def Curve(p1, p2, p3, p4):#计算曲线
p = []
t_p = 100#划分精度
for i in range(0, t_p):
t = i/t_p
x = pow(1-t,3)*p1[0]+3*t*pow(1-t,2)*p2[0]+3*pow(t,2)*(1-t)*p3[0]+pow(t,3)*p4[0]
y = pow(1-t,3)*p1[1]+3*t*pow(1-t,2)*p2[1]+3*pow(t,2)*(1-t)*p3[1]+pow(t,3)*p4[1]
p.append((x,y))
return p
def Distance(p1, p2):#计算距离
d = pow(p1[0]-p2[0],2) + pow(p1[1]-p2[1],2)
d = pow(d,0.5)
return d
d_p = 0.03#两条曲线上的点距小于d_p认为相交
x_p = 0.0001#同一条曲线上的x距离小于x_p则认为是一个点
ps = []
ps1, ps2 = Readf()#读取坐标
bz1 = Curve(ps1[0],ps1[1],ps1[2],ps1[3])#第一条曲线
bz2 = Curve(ps2[0],ps2[1],ps2[2],ps2[3])#第二条曲线
dmin = Distance(bz1[0], bz2[0])
for i in range(len(bz1)):
for j in range(len(bz2)):
d = Distance(bz1[i], bz2[j])#计算各点之间距离
if d < dmin:
dmin = d
if dmin < d_p:
dmin = d_p
for p in ps:
if abs(p[0]-bz1[i][0]) < x_p:
break
else:
ps.append(bz1[i])
print("交点坐标({:.2f},{:.2f})".format(bz1[i][0], bz1[i][1]))
if len(ps) == 0:
print("无交点,最小间距{:.2f}".format(dmin))
测试案例: