思路

滚动的实现思路以及轨迹的存储绘制与我的上一篇博客turtle库绘图:实现滚动五角星并绘制轨迹(1)基本一致,不同之处在于上一篇博客是边绘制边生成轨迹,由于前进距离与旋转角度不容易匹配导致最终的滚动并不是在一个平面上实现的,本博客则是参考了利用Python做一个五角星在平面上滚动问题中的一个回答,通过三角函数预先定义好5个角点的轨迹,保证了滚动是在一个平面上实现的,改进了上一篇博客中的不足。

代码实现

import numpy as np
from turtle import *

r = 50  # 旋转半径
five_corners = np.linspace(0, 360, 5, endpoint=False)  # 五角星初始位置
rotations = np.linspace(0, 720, 181)  # 旋转序列:旋转一周,间隔1°
x_shift = np.linspace(-400, 400, 181)  # 旋转过程中五角星水平位移序列
theta = np.radians(five_corners.reshape(-1, 1) - rotations)  # 计算五角星每个角的旋转弧度序列
x, y = r * np.cos(theta) + x_shift, r * np.sin(theta)  # 计算旋转轨迹上每个角的坐标

setup(1000 + 10, 1000 * 0.618 + 10)
screensize(1000, 1000 * 0.618, 'white')
tracer(False)
speed(0)
hideturtle()
traces = []
pencolors = ['red', 'green', 'gold', 'yellowgreen', 'pink',
             'black', 'purple']
num_points = x.shape[1]
for points_n in range(num_points):
    x_points, y_points = x[:, points_n][[0, 2, 4, 1, 3]], y[:, points_n][[0, 2, 4, 1, 3]]
    traces.append(list(zip(x_points, y_points)))
    pencolor('black')
    pensize(3)
    up()
    goto(x_points[-1], y_points[-1])
    down()
    # print('第%d轮绘制起始点:' % (points_n + 1), pos())
    for x_point, y_point in zip(x_points, y_points):
        goto(x_point, y_point)
    # print('第%d轮绘制终止点:' % (points_n + 1), pos())
    # 用于绘制轨迹
    select_points = np.array(traces)
    select_starts = select_points[0]
    for n in range(5):
        pensize(2)
        select_start_n = select_starts[n]
        select_points_n = select_points[:, n, :]
        pencolor(pencolors[n])
        up()
        goto(select_start_n)
        down()
        for point in select_points_n:
            goto(point)
    update()
    time.sleep(0.02)
    if points_n != num_points - 1:
        clear()
done()

绘制过程改进

在上一篇博客中通过设置画笔颜色与背景相同实现擦除,在运行过程中发现这样会导致绘制闪烁,尤其是在本篇中循环绘制五角星的五条边时尤为明显,因此使用清屏函数进行擦除,同时由于轨迹也会被清空,因此要绘制全部轨迹,而不能只绘制阈值内的轨迹了。

结果

turtle库绘图:实现滚动五角星并绘制轨迹(2)_绘图