import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib.patches as patches
#紙の準備
left = -0.4
right = 2.5
bottom = -0.4
top = 2.5
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title("2019一橋大数学 前期第2問",pad=15)
ax.set_xlim(left,right)
ax.set_ylim(bottom,top)
ax.set_xticks([1,2])
ax.set_yticks([1,2])
ax.tick_params(colors="0.6")
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_position(("data",0))
ax.spines["bottom"].set_position(("data",0))
ax.spines["left"].set_color("0.6")
ax.spines["bottom"].set_color("0.6")
ax.plot(1,0,">",color="0.6",transform=ax.get_yaxis_transform(),clip_on=False)
ax.plot(0,1,"^",color="0.6",transform=ax.get_xaxis_transform(),clip_on=False)
ax.text( 1.03*right,0,"$x$",color="0.6",ha="left",va="center")
ax.text(-0.03*right,top,"$y$",color="0.6",ha="right",va="center")
ax.set_aspect("equal")
#ベクトルを表示させる関数
def show_vector(v,color="0.6",width=0.01):
V = ax.quiver(0,0,v[0],v[1],zorder=10,color=color,width=width,
angles='xy',scale_units='xy',scale=1)
return [V]
#非アニメ部分の描画
pad = 0.03
ax.text(-pad,-pad,"$O$",color="0.6",ha="right",va="top")
arc = patches.Arc((0,0),2,2,0,0,90,ec="0.6",linewidth=2)
ax.add_patch(arc)
a = np.array([2,2])
show_vector(a)
ax.text(2+pad,2+pad,"$A$",color="0.6",ha="left",va="bottom")
#スタート地点
ax.plot(2,0,"or",zorder=20)
#アニメの作成
imgs=[]
p_history = np.empty((0,2))
THETA = np.linspace(0,np.pi/2,91)
for theta in THETA:
img = []
#PとQを動かす
q = np.array([np.cos(theta),np.sin(theta)])
p = np.dot(a,q)*q
img += show_vector(p,color="maroon",width=0.008)
img += show_vector(q,color="0.3")
img += ax.plot(p[0],p[1],"or",zorder=20)
img += ax.plot(q[0],q[1],color="0.3",marker="o",zorder=20)
img += ax.plot([a[0],p[0]],[a[1],p[1]],"0.6",linestyle="dashed")
#お飾り
if theta < 0.24*np.pi:
q_pad = (1+3*pad)*np.array([np.cos(theta-3*pad),np.sin(theta-3*pad)])
img += [ax.text(q_pad[0],q_pad[1],"$Q$",color="0.3",ha="center",va="center")]
p_pad = p+(q_pad-q)
img += [ax.text(p_pad[0],p_pad[1],"$P$",color="r",ha="center",va="center")]
angle = np.rad2deg(theta)+90
deg90 = patches.Rectangle(xy=(p[0],p[1]),width=0.1,height=0.1,
angle=angle,ec="0.6",fill=False)
img+= [ax.add_patch(deg90)]
elif theta > 0.26*np.pi:
q_pad = (1+3*pad)*np.array([np.cos(theta+3*pad),np.sin(theta+3*pad)])
img += [ax.text(q_pad[0],q_pad[1],"$Q$",color="0.3",ha="center",va="center")]
p_pad = p+(q_pad-q)
img += [ax.text(p_pad[0],p_pad[1],"$P$",color="r",ha="center",va="center")]
angle = np.rad2deg(theta)+180
deg90 = patches.Rectangle(xy=(p[0],p[1]),width=0.1,height=0.1,
angle=angle,ec="0.6",fill=False)
img+= [ax.add_patch(deg90)]
#Pの軌跡
p_history = np.vstack([p_history,p])
img+= ax.plot(p_history[:,0],p_history[:,1],"r",linewidth=3)
#すぐには始めない
if theta == 0:
for i in range(30):
imgs.append(img)
else:
imgs.append(img)
#最後の余韻
for i in range(60):
imgs.append(img)
mov=ani.ArtistAnimation(fig, imgs, 100)
plt.show()