标签:main sci app oss end 交点 点线 fit span
numpy.polyfit()
,scipy.optimize()
)# !/usr/bin/env python3
# -*- coding: utf-8 -*-
def find_line(x0, y0):
‘‘‘
根据散点求得端基直线k,b,并得到每点对端基直线的偏差dy
:param x0: x坐标数组
:param y0: y坐标数组
:return: 每点的偏差dy
‘‘‘
# 求得端基直线的k,b
k = (y0[-1] - y0[0]) / (x0[-1] - x0[0])
d = y0[0] - (k * x0[0])
# 根据端基直线的k,b,求得每点对端基直线的偏差dy
dy = [(y0[i] - ((k * x0[i]) + d)) for i in range(len(x0))]
return dy
def find_poly(x_lst, y_lst):
‘‘‘
找到凸多边形,可以包含全部偏差点dy
:param x_lst:x数组
:param y_lst:偏差点dy数组
:return:最佳凸多边形各个点
‘‘‘
g_x = []
g_y = []
# 从起始点开始,向右(x增大方向),找到最大斜率点,再从最大斜率点开始,向右继续寻找
x_tmp = x_lst
y_tmp = y_lst
while len(x_tmp) > 1:
k_lst = [((y_tmp[i] - y_tmp[0]) / (x_tmp[i] - x_tmp[0])) for i in range(0 + 1, len(x_tmp))]
max_k_index = k_lst.index(max(k_lst)) + 1
g_x.append(x_tmp[max_k_index])
g_y.append(y_tmp[max_k_index])
x_tmp = x_tmp[max_k_index:]
y_tmp = y_tmp[max_k_index:]
# 从最末点开始,向左(x减小方向),也找到最大斜率点(有人说找最小斜率点,但是结果算出来不对),再从最大斜率点开始,向左继续寻找
x_tmp = x_lst[::-1]
y_tmp = y_lst[::-1]
while len(x_tmp) > 1:
k_lst = [((y_tmp[i] - y_tmp[0]) / (x_tmp[i] - x_tmp[0])) for i in range(0 + 1, len(x_tmp))]
# max_k_index = k_lst.index(min(k_lst)) + 1 # 算出来不对
max_k_index = k_lst.index(max(k_lst)) + 1
g_x.append(x_tmp[max_k_index])
g_y.append(y_tmp[max_k_index])
x_tmp = x_tmp[max_k_index:]
y_tmp = y_tmp[max_k_index:]
return g_x, g_y
def find_cross(p1, p2, p3):
‘‘‘
根据一个点p1和一条直线(p2和p3的连线),
求得该点对直线的铅垂线(平行于纵轴坐标的直线)和直线的交点
:param p1: 点
:param p2: 线上一点
:param p3: 线上另一点
:return: 铅垂线与线(p2-p3)的交点
‘‘‘
k = (p2[1] - p3[1]) / (p2[0] - p3[0])
b = p2[1] - k * p2[0]
p4 = (p1[0], (k * p1[0]) + b)
return p4
def find_perfect_line(a, b, x0, y0):
‘‘‘
根据凸多边形的每个点,找到凸多边形内最长的一根铅垂线,
与最长垂线相交的直线l1的斜率就是最佳直线的斜率
过最长铅垂线的中点作直线l2平行于直线l1,直线l2为最佳直线
:param a:凸多边形的x轴数组
:param b:凸多边形的y轴数组
:param x0: 实际x轴数组
:param y0: 实际y轴数组
:return:最佳直线的斜率k, 截距b
‘‘‘
p = []
l = []
k_lst = []
b_lst = []
for i in range(len(a)):
p1 = (a[i], b[i])
rp1 = (x0[x0.index(p1[0])], y0[x0.index(p1[0])])
for j in range(len(a)):
p2 = (a[j], b[j])
rp2 = (x0[x0.index(p2[0])], y0[x0.index(p2[0])])
if j == len(a) - 1:
p3 = (a[0], b[0])
else:
p3 = (a[j + 1], b[j + 1])
rp3 = (x0[x0.index(p3[0])], y0[x0.index(p3[0])])
s = find_cross(p1, p2, p3)
if s[0] >= min(a) and s[0] <= max(a) and s[1] >= min(b) and s[1] <= max(b):
p.append(s)
l.append(abs(p1[1] - s[1]))
# 点和直线两端点中点连线的斜率
k = (((rp1[1] + rp2[1]) / 2) - ((rp1[1] + rp3[1]) / 2)) / (
((rp1[0] + rp2[0]) / 2) - ((rp1[0] + rp3[0]) / 2))
k_lst.append(k)
b_lst.append(((rp1[1] + rp2[1]) / 2) - (k * ((rp1[0] + rp2[0]) / 2)))
per_index = l.index(max(l))
k = k_lst[per_index]
b = b_lst[per_index]
return k, b
if __name__ == ‘__main__‘:
x0 = [1.00, 2.00, 3.00, 4.00, 5.00, 6.00]
y0 = [2.02, 4.00, 5.98, 7.90, 10.10, 12.05]
dy = find_line(x0, y0)
a, b = find_poly(x0, dy)
print(find_perfect_line(a, b, x0, y0))
标签:main sci app oss end 交点 点线 fit span
原文地址:https://www.cnblogs.com/sunqim16/p/9121011.html