“利用Python做一个五角星在平面上滚动,把其中一定点的轨迹用matplotlib画出来
”
现只有五角星代码
import numpy as np
import matplotlib.pyplot as plt
r = 1 # 旋转半径
five_corners = np.linspace(18, 378, 5, endpoint=False) # 五角星初始位置
rotations = np.linspace(0, 360, 361) # 旋转序列:旋转一周,间隔1°
x_shift = np.linspace(0, 2*r*np.pi, 361) # 旋转过程中五角星水平位移序列
theta = np.radians(five_corners.reshape(-1,1) - rotations) # 计算五角星每个角的旋转弧度序列
x, y = r*np.cos(theta) + x_shift, r*np.sin(theta) # 计算旋转轨迹上每个角的坐标
plt.plot([x[0][0], x[2][0]], [y[0][0], y[2][0]], color='m', ls='dashed')
plt.plot([x[0][0], x[3][0]], [y[0][0], y[3][0]], color='m', ls='dashed')
plt.plot([x[1][0], x[3][0]], [y[1][0], y[3][0]], color='m', ls='dashed')
plt.plot([x[1][0], x[4][0]], [y[1][0], y[4][0]], color='m', ls='dashed')
plt.plot([x[2][0], x[4][0]], [y[2][0], y[4][0]], color='m', ls='dashed')
for i in range(5):
plt.plot(x[i], y[i]) # 绘制5个角的旋转轨迹
plt.axis('equal') # xy轴等比例保持
plt.show()
这个得花点心思。首先,滚动是绕着某点旋转吧。然后检测碰撞。重现饶新的原点旋转。然后把图形绘画出来,更新
滚动的五角星实际上可以看作是五角星的外接圆在滚动,五角星随之滚动,假设要画轨迹的点是五角星左上的角的顶点,这个点的Y坐标与圆滚动的距离x的关系是可以换算出来的,所以应该是先把五角星的起始点坐标算出来,然后x坐标每增加1,五角星的起始划线角度也是能计算出来的,根据这个理论,有如下实现代码
import turtle as t
import time
from matplotlib import pyplot as plt
import numpy as np
x_list = np.arange(1,600)
r = 40/np.cos(0.1)
y_list = r*(1+np.sin(0.1+x_list/r))
t.Turtle().screen.setworldcoordinates(0,-400,800,400)
t.pensize(2)
t.colormode(255)
t.color(255,215,0)
for x,y in zip(x_list,y_list):
t.clear()
t.goto(x,y)
t.seth(0)
t.right(x*180/(r*np.pi))
t.tracer(10,1)
t.begin_fill()
for i in range(5):
t.fd(80)
t.right(144)
t.end_fill()
t.hideturtle()
t.update()
time.sleep(0.01)
plt.plot(x_list,y_list)
plt.show()
def plant_star_with_color(star_sides, length, colour):
# suggest: star_sides >= 5
color(colour, colour)
begin_fill()
pensize(10)
for s in range(star_sides):
forward(length)
right(720 / star_sides)
# 设置绘制哪一个顶点的轨迹
if s == 2:
place = pos()
forward(length)
left(360 / star_sides)
end_fill()
return place
setup(1000 + 10, 1000 * 0.618 + 10)
screensize(1000, 1000 * 0.618, 'blue')
amount = 150
star_sides = 5
speed(0)
tracer(False)
hideturtle()
start = (-400, 0)
points = []
for i in range(amount):
up()
goto(i * 5 - 400, 0)
down()
# 绘制当前图形
point = plant_star_with_color(star_sides, 20, 'yellow')
update()
# 用于擦除当前绘制的图形,防止出现残影
if i != amount - 1:
time.sleep(0.02)
plant_star_with_color(star_sides, 20, 'blue')
update()
points.append(point)
pencolor('red')
pensize(5)
# 用于绘制轨迹
if len(points) >= 20:
select_points = points[-20:]
select_start = points[-20]
else:
select_points = points
select_start = points[0]
up()
goto(select_start)
down()
for point in select_points:
goto(point)
update()
# 设置旋转角度
seth(0)
right(i * 5)
done()
供参考,通过不断绘制擦除实现滚动效果,滚动的轨迹不是直线,通过turtle库绘制