内摆线动画matplotlib python

2024-10-03 23:26:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试着从维基百科上做这个animation,但是,我很难弄清楚怎么做。基本上我需要做两件事:

  1. 在一个单独的框架中绘制所有的图形。在
  2. 画出最大的圆并保持不变,然后画出最小的圆和内摆线点。但是,我还需要保留内摆线的点,并更新最小圆的位置。在

这是我的代码,但是我有十个不同的帧

import numpy as np
import matplotlib.pyplot as plt
R=3 #Biggest circle radius =3
r=1 #smallest circle radius =1
t=np.linspace(0, 2*np.pi,100) # values from zero to 360 degrees
i=0

xc1=R*np.cos(t) #biggest circle
yc1=R*np.sin(t) #biggest circle
plt.plot(xc1,yc1)

while i<=2*np.pi:
    x=(R-r)*np.cos(i)+r*np.cos((R-r)*i/r) #x values of the hypocycloid
    y=(R-r)*np.sin(i)-r*np.sin((R-r)*i/r)#y value of the hypocycloid
    plt.plot(x,y)  
    i+=2*np.pi/10 

    plt.show()

事先非常感谢。在


Tags: importplotasnppipltsincos
1条回答
网友
1楼 · 发布于 2024-10-03 23:26:55

这里有一个完整的例子,使用OP链接的Wikipedia页面中给出的公式。由于有很多变量需要跟踪,所以我认为最好是在一个类中收集所有的变量。在

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np


class Hypocycloid:

    def __init__(self, ratio = 3, frames = 100, ncycles = 1):
        self.frames = frames
        self.ncycles = ncycles
        self.fig, self.ax = plt.subplots()
        self.ax.set_aspect('equal')

        ##big circle:
        theta = np.linspace(0,2*np.pi,100)
        x = np.cos(theta)
        y = np.sin(theta)

        self.big_circle, = self.ax.plot(x,y,'b-')

        ##small circle:
        self.small_r = 1./ratio
        r = self.small_r
        x = r*np.cos(theta)+1-r
        y = r*np.sin(theta)
        self.small_circle, = self.ax.plot(x,y,'k-')

        ##line and dot:
        self.line, = self.ax.plot([1-r,1],[0,0],'k-')
        self.dot, = self.ax.plot([1-r],[0], 'ko', ms=5)
        ##hypocycloid:
        self.hypocycloid, = self.ax.plot([],[],'r-')


        self.animation = FuncAnimation(
            self.fig, self.animate,
            frames=self.frames*self.ncycles,
            interval=50, blit=False,
            repeat_delay=2000,
        )


    def update_small_circle(self, phi):
        theta = np.linspace(0,2*np.pi,100)
        x = self.small_r*np.cos(theta)+(1-self.small_r)*np.cos(phi)
        y = self.small_r*np.sin(theta)+(1-self.small_r)*np.sin(phi)
        self.small_circle.set_data(x,y)


    def update_hypocycloid(self, phis):
        r = self.small_r
        x = (1-r)*np.cos(phis)+r*np.cos((1-r)/r*phis)
        y = (1-r)*np.sin(phis)-r*np.sin((1-r)/r*phis)
        self.hypocycloid.set_data(x,y)

        center = [(1-r)*np.cos(phis[-1]), (1-r)*np.sin(phis[-1])]

        self.line.set_data([center[0],x[-1]],[center[1],y[-1]])
        self.dot.set_data([center[0]], [center[1]])

    def animate(self, frame):
        frame = frame+1
        phi = 2*np.pi*frame/self.frames
        self.update_small_circle(phi)
        self.update_hypocycloid(np.linspace(0,phi,frame))

hypo = Hypocycloid(ratio=3.25, frames = 40, ncycles=4)

##un-comment the next line, if you want to save the animation as gif:
##hypo.animation.save('hypocycloid.gif', writer='imagemagick', fps=10, dpi=75)

plt.show()

可以传递给Hypocycloid类的参数是ratio(小圆相对于大圆的半径)、frames(小圆绕大圆一次行程的帧数)和ncycles(行程数)。ratio=3.25frames=40ncycles=4的最终结果如下:

result of above code

相关问题 更多 >