import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# Set up the figure and axis
fig, ax = plt.subplots()
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
ax.set_aspect('equal')
ax.axis('off')
# Create a circle to represent the structure (e.g., a muscle or valve)
circle = plt.Circle((0, 0), 0.5, color='pink', fill=True)
ax.add_artist(circle)
# Create two points to represent fingers
finger1, = ax.plot([], [], 'o', color='red', markersize=10)
finger2, = ax.plot([], [], 'o', color='blue', markersize=10)
# Initialize the animation
def init():
finger1.set_data([], [])
finger2.set_data([], [])
return finger1, finger2
# Update function for the animation
def update(frame):
# Simulate the movement of two fingers opening and closing
angle = np.radians(frame) # Convert frame to radians
radius = 0.8 # Distance from the center
# Position of the first finger (red)
x1
= radius
* np.
cos(angle
) y1
= radius
* np.
sin(angle
)
# Position of the second finger (blue)
x2
= -radius
* np.
cos(angle
) y2
= -radius
* np.
sin(angle
)
# Update the positions of the fingers
finger1.set_data(x1, y1)
finger2.set_data(x2, y2)
# Adjust the size of the circle based on the distance between fingers
distance
= np.
sqrt((x1
- x2
)**2 + (y1
- y2
)**2) circle_radius = 0.5 + 0.2 * (1 - distance / (2 * radius)) # Scale the circle
circle.set_radius(circle_radius)
return finger1, finger2, circle
# Create the animation
ani = FuncAnimation(fig, update, frames=np.linspace(0, 360, 180), init_func=init, blit=True)
# Show the animation
plt.show()
aW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBtYXRwbG90bGliLnB5cGxvdCBhcyBwbHQKZnJvbSBtYXRwbG90bGliLmFuaW1hdGlvbiBpbXBvcnQgRnVuY0FuaW1hdGlvbgoKIyBTZXQgdXAgdGhlIGZpZ3VyZSBhbmQgYXhpcwpmaWcsIGF4ID0gcGx0LnN1YnBsb3RzKCkKYXguc2V0X3hsaW0oLTEuNSwgMS41KQpheC5zZXRfeWxpbSgtMS41LCAxLjUpCmF4LnNldF9hc3BlY3QoJ2VxdWFsJykKYXguYXhpcygnb2ZmJykKCiMgQ3JlYXRlIGEgY2lyY2xlIHRvIHJlcHJlc2VudCB0aGUgc3RydWN0dXJlIChlLmcuLCBhIG11c2NsZSBvciB2YWx2ZSkKY2lyY2xlID0gcGx0LkNpcmNsZSgoMCwgMCksIDAuNSwgY29sb3I9J3BpbmsnLCBmaWxsPVRydWUpCmF4LmFkZF9hcnRpc3QoY2lyY2xlKQoKIyBDcmVhdGUgdHdvIHBvaW50cyB0byByZXByZXNlbnQgZmluZ2VycwpmaW5nZXIxLCA9IGF4LnBsb3QoW10sIFtdLCAnbycsIGNvbG9yPSdyZWQnLCBtYXJrZXJzaXplPTEwKQpmaW5nZXIyLCA9IGF4LnBsb3QoW10sIFtdLCAnbycsIGNvbG9yPSdibHVlJywgbWFya2Vyc2l6ZT0xMCkKCiMgSW5pdGlhbGl6ZSB0aGUgYW5pbWF0aW9uCmRlZiBpbml0KCk6CiAgICBmaW5nZXIxLnNldF9kYXRhKFtdLCBbXSkKICAgIGZpbmdlcjIuc2V0X2RhdGEoW10sIFtdKQogICAgcmV0dXJuIGZpbmdlcjEsIGZpbmdlcjIKCiMgVXBkYXRlIGZ1bmN0aW9uIGZvciB0aGUgYW5pbWF0aW9uCmRlZiB1cGRhdGUoZnJhbWUpOgogICAgIyBTaW11bGF0ZSB0aGUgbW92ZW1lbnQgb2YgdHdvIGZpbmdlcnMgb3BlbmluZyBhbmQgY2xvc2luZwogICAgYW5nbGUgPSBucC5yYWRpYW5zKGZyYW1lKSAgIyBDb252ZXJ0IGZyYW1lIHRvIHJhZGlhbnMKICAgIHJhZGl1cyA9IDAuOCAgIyBEaXN0YW5jZSBmcm9tIHRoZSBjZW50ZXIKICAgIAogICAgIyBQb3NpdGlvbiBvZiB0aGUgZmlyc3QgZmluZ2VyIChyZWQpCiAgICB4MSA9IHJhZGl1cyAqIG5wLmNvcyhhbmdsZSkKICAgIHkxID0gcmFkaXVzICogbnAuc2luKGFuZ2xlKQogICAgCiAgICAjIFBvc2l0aW9uIG9mIHRoZSBzZWNvbmQgZmluZ2VyIChibHVlKQogICAgeDIgPSAtcmFkaXVzICogbnAuY29zKGFuZ2xlKQogICAgeTIgPSAtcmFkaXVzICogbnAuc2luKGFuZ2xlKQogICAgCiAgICAjIFVwZGF0ZSB0aGUgcG9zaXRpb25zIG9mIHRoZSBmaW5nZXJzCiAgICBmaW5nZXIxLnNldF9kYXRhKHgxLCB5MSkKICAgIGZpbmdlcjIuc2V0X2RhdGEoeDIsIHkyKQogICAgCiAgICAjIEFkanVzdCB0aGUgc2l6ZSBvZiB0aGUgY2lyY2xlIGJhc2VkIG9uIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIGZpbmdlcnMKICAgIGRpc3RhbmNlID0gbnAuc3FydCgoeDEgLSB4MikqKjIgKyAoeTEgLSB5MikqKjIpCiAgICBjaXJjbGVfcmFkaXVzID0gMC41ICsgMC4yICogKDEgLSBkaXN0YW5jZSAvICgyICogcmFkaXVzKSkgICMgU2NhbGUgdGhlIGNpcmNsZQogICAgY2lyY2xlLnNldF9yYWRpdXMoY2lyY2xlX3JhZGl1cykKICAgIAogICAgcmV0dXJuIGZpbmdlcjEsIGZpbmdlcjIsIGNpcmNsZQoKIyBDcmVhdGUgdGhlIGFuaW1hdGlvbgphbmkgPSBGdW5jQW5pbWF0aW9uKGZpZywgdXBkYXRlLCBmcmFtZXM9bnAubGluc3BhY2UoMCwgMzYwLCAxODApLCBpbml0X2Z1bmM9aW5pdCwgYmxpdD1UcnVlKQoKIyBTaG93IHRoZSBhbmltYXRpb24KcGx0LnNob3coKQ==