import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
L = 2
f1 = 1
f2 = 1.5
A1 = 1
A2 = 0.8
fig = plt.figure ( figsize= ( 7 , 7 ) )
ax1 = fig.add_subplot ( 2 , 1 , 1 , xlim = ( -3 , 3 ) , ylim = ( -3 , 1 ) )
line1, = ax1.plot ( [ ] , [ ] , 'y-' , lw = 2 )
line2, = ax1.plot ( [ ] , [ ] , 'b-' , lw = 2 )
bob1, = ax1.plot ( [ ] , [ ] , 'oy' )
bob2, = ax1.plot ( [ ] , [ ] , 'ob' )
ax2 = fig.add_subplot ( 2 , 1 , 2 , xlim = ( 0 , 10 ) , ylim = ( -1.5 , -1.5 ) )
t_data = np.linspace ( 0 , 10 , 500 )
py, = ax2.plot ( [ ] , [ ] , 'y-' )
pb, = ax2.plot ( [ ] , [ ] , 'b-' )
def init( ) :
line1.set_data ( [ ] , [ ] )
line2.set_data ( [ ] , [ ] )
bob1.set_data ( [ ] , [ ] )
bob2.set_data ( [ ] , [ ] )
py.set_data ( [ ] , [ ] )
pb.set_data ( [ ] , [ ] )
return line1, line2, bob1, bob2, py, pb
def update( i) :
t = i/50
th1 = A1*np.cos ( 2 *np.pi *f1*t)
th2 = A2*np.cos ( 2 *np.pi *f2*t + np.pi /4 )
x1 = L*np.sin ( th1)
y1 = L*np.cos ( th1)
x2 = L*np.sin ( th2)
y2 = L*np.cos ( th2)
line1.set_data ( [ 0 , x1] , [ 0 , y1] )
line2.set_data ( [ 0 , x2] , [ 0 , y2] )
bob1.set_data ( [ x1] , [ y1] )
bob2.set_data ( [ x2] , [ y2] )
idx = np.searchsorted ( t_data, t)
py.set_data ( t_data[ :idx] , A1*np.cos ( 2 *np.pi *f1*t_data[ :idx] ) )
pb.set_data ( t_data[ :idx] , A2*np.cos ( 2 *np*f2*t_data[ :idx] + np.pi /4 ) )
if t> 8 : ax2.set_xlim ( t - 8 , t + 2 )
return line1, line2, bob1, bob2, py, pb
ani = FuncAnimation( fig, update, frames = 500 , init_func = init, blit = True , interval = 20 )
plt .tight_layout ( )
plt.show ( )
aW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBtYXRwbG90bGliLnB5cGxvdCBhcyBwbHQKZnJvbSBtYXRwbG90bGliLmFuaW1hdGlvbiBpbXBvcnQgRnVuY0FuaW1hdGlvbgoKTCA9IDIKZjEgPSAxCmYyID0gMS41CkExID0gMQpBMiA9IDAuOAoKZmlnID0gcGx0LmZpZ3VyZShmaWdzaXplPSg3LDcpKQpheDEgPSBmaWcuYWRkX3N1YnBsb3QoMiwxLDEseGxpbSA9ICgtMywzKSx5bGltID0gKC0zLDEpKQpsaW5lMSwgPSBheDEucGxvdChbXSxbXSwneS0nLCBsdyA9IDIpCmxpbmUyLCA9IGF4MS5wbG90KFtdLFtdLCdiLScsIGx3ID0gMikKYm9iMSwgPSBheDEucGxvdChbXSxbXSwnb3knKQpib2IyLCA9IGF4MS5wbG90KFtdLFtdLCdvYicpCgpheDIgPSBmaWcuYWRkX3N1YnBsb3QoMiwxLDIsIHhsaW0gPSAoMCwxMCksIHlsaW0gPSAoLTEuNSwgLTEuNSkpCnRfZGF0YSA9IG5wLmxpbnNwYWNlKDAsMTAsNTAwKQpweSwgPSBheDIucGxvdChbXSxbXSwneS0nKQpwYiwgPSBheDIucGxvdChbXSxbXSwnYi0nKQoKZGVmIGluaXQoKToKICAgIGxpbmUxLnNldF9kYXRhKFtdLFtdKQogICAgbGluZTIuc2V0X2RhdGEoW10sW10pCiAgICBib2IxLnNldF9kYXRhKFtdLFtdKQogICAgYm9iMi5zZXRfZGF0YShbXSxbXSkKICAgIHB5LnNldF9kYXRhKFtdLFtdKQogICAgcGIuc2V0X2RhdGEoW10sW10pCiAgICByZXR1cm4gbGluZTEsIGxpbmUyLCBib2IxLCBib2IyLCBweSwgcGIKCmRlZiB1cGRhdGUoaSk6CiAgICB0ID0gaS81MAogICAgdGgxID0gQTEqbnAuY29zKDIqbnAucGkqZjEqdCkKICAgIHRoMiA9IEEyKm5wLmNvcygyKm5wLnBpKmYyKnQgKyBucC5waS80KQoKICAgIHgxID0gTCpucC5zaW4odGgxKQogICAgeTEgPSBMKm5wLmNvcyh0aDEpCiAgICB4MiA9IEwqbnAuc2luKHRoMikKICAgIHkyID0gTCpucC5jb3ModGgyKQoKICAgIGxpbmUxLnNldF9kYXRhKFswLCB4MV0sWzAsIHkxXSkKICAgIGxpbmUyLnNldF9kYXRhKFswLCB4Ml0sIFswLCB5Ml0pCiAgICBib2IxLnNldF9kYXRhKFt4MV0sW3kxXSkKICAgIGJvYjIuc2V0X2RhdGEoW3gyXSwgW3kyXSkKCiAgICBpZHggPSBucC5zZWFyY2hzb3J0ZWQodF9kYXRhLHQpCiAgICBweS5zZXRfZGF0YSh0X2RhdGFbOmlkeF0sIEExKm5wLmNvcygyKm5wLnBpKmYxKnRfZGF0YVs6aWR4XSkpCiAgICBwYi5zZXRfZGF0YSh0X2RhdGFbOmlkeF0sIEEyKm5wLmNvcygyKm5wKmYyKnRfZGF0YVs6aWR4XSArIG5wLnBpLzQpKQoKICAgIGlmIHQ+ODogYXgyLnNldF94bGltKHQgLSA4LCB0ICsgMikKICAgIHJldHVybiBsaW5lMSwgbGluZTIsIGJvYjEsIGJvYjIsIHB5LCBwYgoKYW5pID0gRnVuY0FuaW1hdGlvbihmaWcsIHVwZGF0ZSwgZnJhbWVzID0gNTAwLCBpbml0X2Z1bmMgPSBpbml0LCBibGl0ID0gVHJ1ZSwgaW50ZXJ2YWwgPSAyMCkKcGx0IC50aWdodF9sYXlvdXQoKQpwbHQuc2hvdygp