python读取坐标数据画出最⼤⾯积的轮廓
项⽬要求,现需要⼀个能根据Excel的坐标数据,在图像上进⾏描点连线,并且连线的⽅式是以所有的点进⾏最⼤轮廓连线。现在实现了要求,但是由于代码写得太乱,我只是简单的说⼀下实现算法就好了,代码也会贴出来,时间过于久,我也有些地⽅忘记了,但是整体算法还是记得的~
下⾯开始简单的说⼀下:
⾸先,所有点的坐标数据就像下图所⽰:
问题:如何将所有的点以最⼤的轮廓连线呢??
思路:应该是数学问题,如何将坐标列表重新排序成以最⼤轮廓的坐标列表,因为matplotlib库可以根据⼀个列表⾥⾯的坐标数据直接⽣成连线。
我的排序算法是:
1.⾸先,将所有坐标进⾏排序,可以以x排序,然后到最左边的坐标点和最右边的坐标;
2.以最左边和最右边的坐标进⾏求解⽅程,两点确定⼀条直线,就是求该直线的⽅程;
3.将剩余的所有坐标x代⼊步骤2的⽅程组,求出解和坐标y进⾏⽐较,将线下⽅的点和上⽅的点坐标分别求出来,然后存⼊⼀个列表备份;
4.将下⽅坐标的列表进⾏排序,由⼩到⼤,然后存⼊⼀个最终列表中,最终列表第⼀个肯定是最左边的点,然后就是下⽅的点;
5.将下⽅坐标的列表进⾏排序,由⼤到⼩,然后继续分别存⼊最终列表,最后在最终列表中在加上最左边的坐标点,使连线闭合;
6.然后⽤matplotlib⾥⾯的pyplot函数,将最终列表连线即可。
上⾯的算法我写在了⼀个函数⾥⾯,这是⾮常不对的,但是如今还是不想将其整理出来,哈哈,思维不乱就⾏~~
1try:
2# 先提取成⼀个个位置坐标
3 coordinate = []
4for i in range(len(x)):
5 coordinate.append([x[i], y[i]])
6
7# print(coordinate)
8
余切函数图像和正切函图像9# 这是基准列表,x最⼩最⼤,y最⼩最⼤
10 sort_list = []
11# 剩下的坐标数据
12 ret_list = []
13# 下⽅的点数据
14 under_list = []
15# 总的排序结果
16 final_list = []
17# 临时列表
18 temp = []
19
20# 下⽅的点
21 down_dot = []
22# 上⽅的点
23 up_dot = []
24
25 y_max_and_y_min = []
26
27# 进⾏x排序
28 sort_x(coordinate)
29
30# 排序完成肯定是第⼀个最⼩,最后⼀个最⼤,将这两个数据添加到确定的基准列表⾥⾯
31 sort_list.append(coordinate[0])
32 sort_list.append(coordinate[len(coordinate) - 1])
33
34# 这下⾯进⾏以y⼤⼩进⾏排序,,重新存储在⼀个新列表⾥⾯
35 sort_y(coordinate)
36 y_max_and_y_min.append(coordinate[0])
37 y_max_and_y_min.append(coordinate[len(coordinate) - 1])
38
39# 这句代码实现的功能是和基准列表进⾏⽐对,求除了基准列表剩下的所有坐标数据
40 ret_list = [item for item in coordinate if item not in sort_list] + [item for item in sort_list if
41 item not in coordinate]
42
43print("确定的坐标:" + str(sort_list))
44
45print("剩余的坐标: " + str(ret_list))
46
47# 最左坐标
48 left_x = sort_list[0][0]
49 left_y = sort_list[0][1]
50
51# 最右坐标
52 right_x = sort_list[1][0]
53 right_y = sort_list[1][1]
54
55# 最下坐标
56 down_x = y_max_and_y_min[0][0]
57 down_y = y_max_and_y_min[0][1]
58
59# 最上坐标
60 up_x = y_max_and_y_min[1][0]
61 up_y = y_max_and_y_min[1][1]
62
63# 实现两点之间的公式
64# y = k*x + b
65
66# 总判断公式,,蛮重要
67 k = (right_y - left_y) / (right_x - left_x)
68 b = left_y - k * left_x
69
70print("y=" + str(k) + "x" + '+' + str(b))
71
72# 开始进⾏⽐对,判断剩余列表⾥⾯的每⼀个点,如果在直线下⽅,就加⼊下⽅列表⾥⾯
73for i in range(len(ret_list)):
74# print(ret_list[i])
75if (under(k, b, ret_list[i])):
76 under_list.append(ret_list[i])
77
78print("下⾯列表的数据", under_list)
79
80# 对下⽅列表再以x为基准进⾏排序
81 under_list = sort_x(under_list)
82
html空格是什么83# 排序完成直接都添加到确定的列表⾥⾯,先添加⼀个最左的坐标,在循环结束之后再添加最右的数据 84 final_list.append(sort_list[0])
85
86for t in under_list:
87 final_list.append(t)
88# 边添加还边让数据从剩余列表⾥⾯去掉
89 ve(t)
90
91 final_list.append(sort_list[1])
92
93>>>>>>>>>>>>>>>> 94# 到此,,下⽅的排序已经结束
95print(final_list)
96 num_under = len(final_list)
97
98print(ret_list)
99
100# 剩下的列表进⾏冒泡排序,还是由⼩到⼤,但是最后翻转⼀下列表就可以
101 ret_list = sort_x(ret_list)
102 ret_list = (list(reversed(ret_list)))
103
104print(ret_list)
105
106for t in ret_list:
107"""将剩下的坐标添加到处理后的列表⾥⾯"""
108 final_list.append(t)
109
110# 这个是再补⼀个坐标,使曲线闭合
111 final_list.append(sort_list[0])
112
113print(ret_list)
114print("最终列表-----------", final_list)
115
116# 分离后的x,y坐标数据
117 final_x = []
118 final_y = []
119
120for i in range(len(final_list)):
121"""将坐标数据从新分离成两个列表"""
122 final_x.append(final_list[i][0])
123 final_y.append(final_list[i][1])python入门教程网盘
124
125# print(final_x)
126# print(final_y)
127
128# 在这需要将列表翻装⼀下,调试好久才发现
129 final_list = list(reversed(final_list))
130
131# 将图像显⽰出来
132# showResult(final_x, final_y,'title', 'x', 'y')边框图案设计图片
View Code
连线起来的最终效果图:
项⽬要求2: 判断⼀个点是否在所围的轮廓内。
实现⽅法:
1.⾸先判断是否在x坐标是否在最左,最右之间,y坐标是否在最上,最下坐标之间,如果不在,直接判定不在;
2.判断是否为原来数据的点,如果是直接判定在轮廓内;
3.然后将需要判断的坐标代⼊最左最右组成的⽅程上,判断该坐标是该直线的上⽅还是下⽅。
4.若在下⽅,判断在下⽅的坐标点哪两个坐标之间,根据左右两个坐标点进⾏直线⽅程的求解,然后将需判断坐标的x代⼊,求解是否⼤于y坐标,如果⼤于就判定是在轮廓⾥⾯;
5.若在上⽅,判定条件改成⼩于才在轮廓⾥⾯;
代码如下:
# 下⾯进⾏判断⼀个点是否在圈内
# x_judge = 0.396
# y_judge = 0.592
x_get = self.()
y_get = self.()
if (len(x_get)==0):
x_judge = final_x[0]
y_judge = final_y[0]
judge = [float(x_judge), float(y_judge)]
self.input_x.setText(str(x_judge))
self.input_y.setText(str(y_judge))
else:
x_judge = float(x_get)
y_judge = float(y_get)
judge = [float(x_judge), float(y_judge)]
if judge == sort_list[0] or judge == sort_list[1] or judge == y_max_and_y_min[0] or judge == \
y_max_and_y_min[1]:
"""先判断是否是基准点"""
print("在--相等")
flag=True
elif is_midle(judge[0], left_x, right_x) and is_midle(judge[1], down_y, up_y):
"""先判断是否在⼤圈之内"""
# 先判断是在上⽅的点还是上⽅的点,如果在下⽅⽤下⽅的公式,否则,相反
if not under(k, b, judge):
print("在下⽅")
for i in range(len(down_dot) - 1):
if is_midle(judge[0], down_dot[i][0], down_dot[i + 1][0]):
# print(down_dot[i][0],down_dot[i+1][0])
print(down_dot[i], down_dot[i + 1])
k_test, b_test = generate_equation(down_dot[i], down_dot[i + 1]) print(k_test, b_test)
if not (under(k_test, b_test, judge)):
print("不在")
flag = False
俄罗斯方块java课程设计
break
else:
print("在")
flag = True
break
else:
pass
elif not up_under(k, b, judge):
print("在上⽅")
for i in range(len(up_dot) - 1):
if is_midle(judge[0], up_dot[i + 1][0], up_dot[i][0]):
print(up_dot[i], up_dot[i + 1])
k_test, b_test = generate_equation(up_dot[i], up_dot[i + 1])
print(k_test, b_test)
if (up_under(k_test, b_test, judge)):
print("在")
flag = True
break
else:
print("不在")
flag=False
break
else:
pass
else:
print("不在")
flag = False
if (flag == True):
plt.scatter(x_judge, y_judge, color='green', marker='o')
elif (flag == False):
plt.scatter(x_judge,y_judge,color='red',marker='o')
plt.plot(final_x, final_y, color='black', linewidth=2.0)
plt.scatter(final_x, final_y, color='black', marker='+')
plt.title(str(flag))
茶艺入门视频教程全集plt.xlabel('x')
plt.ylabel('y')
for x1, y1 in zip(final_x, final_y):
<(x1,y1, str(x1), ha='center', va='bottom', fontsize=10.5)
for x2, y2 in zip(final_x, final_y):
<(x2+0.1,y2, str(y2), ha='center', va='bottom', fontsize=10.5)
plt.show()
View Code
⾄此,项⽬的要求算为完成,然后组成了GUI界⾯,所⽤的库是PYQT5。其实这个库真的挺好⽤的。
说下打包成exe 的时候遇到的问题,最新版的matplotlib库⽤pyinstaller根据打包不成功,如果按照⽹上的说法⼀个个依赖去寻,太过于⿇烦,我查了半天资料,发现有个⼤佬说旧版的matplotlib可以,我连忙卸载新版的,下载旧版的,打包,,成功。就很完美~~~
⾄此,项⽬结束。
完成代码我放在了我的⽹盘上,有点点乱~下⾯是⽹盘链接:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
Typora序列号使用全过程(Github开源)
« 上一篇
利用Python展示文件下载进度条
下一篇 »
发表评论