前情提要
如题,最近在看Bones,应该是第三季的前几集,Angela通过骨头上(还是什么物品上)的点,制作出可能的图案动画,接着女主的鹰眼能力发动,指出图案应该是属于Gormogon?的图腾还是啥。总之,我试图复刻一下,画图不难,就是穷举实在是太爆炸了,假如有十个点,就有10!=3628800种可能,0.1s过一帧看完都需要4天多一点,而且万一正确答案晃过去了,那就更……(所以电视剧就是电视剧233333)
代码
python
用到的包
- matplotlib
random- itertools
封闭图案
直接上Polygon
,以前只会画画散点图、折线图之类的,看来对matplotlib这个包学的还不够透彻。
import random
import itertools
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.animation import FuncAnimation
# 生成5个随机点
# x = [random.randint(0, 100) for i in range(5)]
# y = [random.randint(0, 100) for i in range(5)]
# 这些点能组成一个向上的箭头
x = [2.5,1,2,3,4,2,3]
y = [5,3,3,3,3,1,1]
points = list(zip(x, y))
# 获取所有可能的点的排列组合
all_points = list(itertools.permutations(points))
# 排序
all_points.sort()
# 初始化图形
fig, ax = plt.subplots()
ax.set_title(f"All Closed Shapes with {len(x)} Points")
ax.set_xlim(0, 5) # 设置x轴界限以容纳随机点
ax.set_ylim(0, 5) # 设置y轴界限以容纳随机点
ax.scatter(x,y,color='r')
# 初始化一个空的多边形集合
polygons = []
# 定义动画更新函数
def update(num):
# 清除之前的多边形
for poly in polygons:
poly.remove()
polygons.clear()
# 获取当前排列的点
point = all_points[num % len(all_points)]
# 创建多边形并添加到坐标轴
polygon = patches.Polygon(point, closed=True, color='b', alpha=0.5,fill=False)
ax.add_patch(polygon)
# 将多边形添加到集合中,以便后续清除
polygons.append(polygon)
# 暂停一段时间以便观察
plt.pause(0.1)
# 返回列表,虽然这里不需要
return polygons
# 创建动画
ani = FuncAnimation(fig, update, frames=range(len(all_points)), blit=True)
# 显示图形和动画
plt.show()
展示
讨论
本人数学很烂,感觉这个东西应该涉及到图论相关的知识,不过总归是可以设计一些规则过滤掉那些太离谱的形状,比如说:
- 两点之间距离过远,e.g. 左上和右下的点相连的可能就比较低,在穷举过程中应该把它们往后稍稍
- 一个点应该先与临近的点相连,不过上面代码中只是简单的
sort
,其实应该算欧氏距离
进行sort
的 - …(欢迎评论区提出其他见解)