問題文
次のように媒介変数表示された $xy$ 平面上の曲線を $C$ とする。 $$\begin{eqnarray}\left\{\begin{array}{l}x=3\cos t-\cos 3t\\y=3\sin t-\sin 3t\end{array}\right.\end{eqnarray}$$ ただし、 $0\leqq t \leqq\frac{\pi}{2}$ である。
- $\frac{dx}{dt}$ および $\frac{dy}{dt}$ を計算し、 $C$ の概形を図示せよ。
- $C$ と $x$ 軸と $y$ 軸で囲まれた部分の面積を求めよ。
(2016 東京工業大学 前期第5問)
- $\frac{dx}{dt}=-3\sin t+3\sin 3t$
$\frac{dy}{dt}=3\cos t-3\cos 3t$ - $3\pi$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib.gridspec as gridspec
from matplotlib.colors import ListedColormap
#紙の準備
bgc = "0.5"
fig = plt.figure()
fig.canvas.draw()
fig.suptitle("2016東工大数学 前期第5問",
color=bgc,ha="right",x=0.95,y=0.95,zorder=-1)
fig.subplots_adjust(left=0.05,right=0.95,top=0.75)
gs = gridspec.GridSpec(1,10)
#図形を描く部分
ax1 = fig.add_subplot(gs[0,0:3])
ax1.set_xlim(-0.5,3.5)
ax1.set_ylim(-0.5,4.5)
ax1.set_xticks([2])
ax1.set_xticklabels(["$2$"])
ax1.set_yticks([4])
ax1.set_yticklabels(["$4$"])
ax1.tick_params(width=0,colors=bgc)
ax1.spines["left"].set_position(("data",0))
ax1.spines["bottom"].set_position(("data",0))
ax1.spines["left"].set_color(bgc)
ax1.spines["bottom"].set_color(bgc)
ax1.plot(1,0,">",color=bgc,transform=ax1.get_yaxis_transform(),clip_on=False)
ax1.plot(0,1,"^",color=bgc,transform=ax1.get_xaxis_transform(),clip_on=False)
ax1.spines["top"].set_visible(False)
ax1.spines["right"].set_visible(False)
ax1.set_aspect("equal")
#積分をガリガリやる部分
ax2 = fig.add_subplot(gs[0,3:])
width = 8
height = 4
ax2.set_xlim(0,width)
ax2.set_ylim(0,height)
ax2.set_aspect("equal")
ax2.axis("off")
#フォント辞書たち
linedic={
"usetex" : True,
"clip_on" : True,
"animated" : True,
"fontsize" : 18,
"verticalalignment" : "baseline",
}
formuladic={
"color" : bgc,
"usetex" : True,
"fontsize" : 22,
}
annotatedic={
"facecolor" : "white",
"edgecolor" : "white",
"pad" : 0,
}
commentdic={
"ha" : "center",
"va" : "center",
"size" : 20,
"color" : "white",
"animated" : True,
"fontfamily": "Meiryo",
}
commentbgdic={
"facecolor" : "black",
"pad" : 300,
}
#台本
lines_dx=[
r"= \int_0^{2\sqrt{2}} y_{\,\mathrm{up}} \,dx - \int_2^{2\sqrt{2}} y_{\,\mathrm{down}} \,dx",
r"= \int_{\frac{\pi}{2}}^0 y \,\frac{dx}{dt} \,dt",
r"= \int_{\frac{\pi}{2}}^0\!(3\sin\!t\!-\!\sin\!3t)(-3\sin\!t\!+\!3\sin\!3t)\,dt",
r"= -3\!\int_{\frac{\pi}{2}}^0\!(3\sin^2\!t\!-\!4\sin\!3t\sin\!t\!+\!\sin^2\!3t)\,dt",
r"= 3\!\!\int_0^{\frac{\pi}{2}}\!\!\{\textstyle\frac{3-3\cos\!2t}{2}\!+\scriptstyle2(\cos\!4t-\cos\!2t)\textstyle\!+\!\frac{1-\cos\!6t}{2}\displaystyle\}dt",
r"= 3\left(\frac{3}{2}\cdot\frac{\pi}{2}+\frac{1}{2}\cdot\frac{\pi}{2}\right) = 3\pi",
]
comment="""\
もしくは
"""
lines_dy=[
r"= \int_0^4 x \,dy",
r"= \int_0^{\frac{\pi}{2}} x \,\frac{dy}{dt} \,dt",
r"= \int_0^{\frac{\pi}{2}}\!(3\cos\!t\!-\!\cos\!3t)(3\cos\!t\!-\!3\cos\!3t)\,dt",
r"= 3\!\int_0^{\frac{\pi}{2}}\!(3\cos^2\!t\!-\!4\cos\!3t\cos\!t\!+\!\cos^2\!3t)\,dt",
r"= 3\!\!\int_0^{\frac{\pi}{2}}\!\!\{\textstyle\frac{3+3\cos\!2t}{2}\!-\scriptstyle2(\cos\!4t+\cos\!2t)\textstyle\!+\!\frac{1+\cos\!6t}{2}\displaystyle\}dt",
r"= 3\left(\frac{3}{2}\cdot\frac{\pi}{2}+\frac{1}{2}\cdot\frac{\pi}{2}\right) = 3\pi",
]
#非アニメ部分の描画(曲線と与式)
#軸まわり
ax1.text(-0.1,-0.1,"$\mathrm{O}$",
color=bgc,ha="right",va="top")
ax1.text( 3.5, 0.2,"$\mathrm{x}$",
color=bgc,ha="right",va="bottom")
ax1.text(-0.2, 4.5,"$\mathrm{y}$",
color=bgc,ha="right",va="bottom")
#与式とその微分
ax1.text( 0.1, 6.4,r"$x\,=3\cos\!t\!-\!\cos\!3t$",
fontdict=formuladic)
ax1.text( 7.1, 6.4,r"$y\,=3\sin\!t\!-\!\sin\!3t$",
fontdict=formuladic)
ax1.text( 0.0, 5.2,r"$\frac{dx}{dt}=-3\sin\!t\!+\!3\sin\!3t$",
fontdict=formuladic)
ax1.text( 7.0, 5.2,r"$\frac{dy}{dt}= 3\cos\!t\!-\!3\cos\!3t$",
fontdict=formuladic)
#求める面積
t = np.linspace(0,np.pi/2,100)
x = 3*np.cos(t)-np.cos(3*t)
y = 3*np.sin(t)-np.sin(3*t)
ax1.fill(np.append(0,x),np.append(0,y),
fill=False,ec=bgc,hatch="///")
#曲線の具体的説明
ax1.plot([0,2*np.sqrt(2),2*np.sqrt(2)],[np.sqrt(2),np.sqrt(2),0],
color=bgc,linestyle="dashed",linewidth=0.75)
ax1.text(2*np.sqrt(2),-0.1,"$2\\sqrt{2}$",
color=bgc,ha="center",va="top")
ax1.text(-0.1,np.sqrt(2),"$\\sqrt{2}$",
color=bgc,ha="right",va="center")
ax1.plot(2*np.sqrt(2),np.sqrt(2),color=bgc,marker=".")
ax1.text(2*np.sqrt(2)-0.2,np.sqrt(2)+0.1,"$t=\\frac{\pi}{4}$",bbox=annotatedic,
color=bgc,ha="right",va="bottom")
ax1.plot(2,0,color=bgc,marker=".")
ax1.text(1.9,0.1,"$t=0$",bbox=annotatedic,
color=bgc,ha="right",va="bottom")
ax1.plot(0,4,color=bgc,marker=".")
ax1.text(0.2,4.0,"$t=\\frac{\pi}{2}$",
color=bgc,ha="left",va="bottom")
#数式アニメのための準備
base = height/5
delta = 0.1
colors = [(1,1,1,alpha) for alpha in np.arange(0,11)/10]
cmap = ListedColormap(colors)
ax2.text(-0.2,base+height/2,"$S$",fontdict=linedic,
ha="right",clip_on=False,animated=False)
#数式をLATEX変換する関数
def show_line(y,line,alpha=1.0):
img = []
line = "$\\displaystyle " + line + "$"
text = ax2.text(0,y,line,alpha=alpha,fontdict=linedic)
img += [text]
bbox = text.get_window_extent().transformed(ax2.transData.inverted())
right = bbox.x1
return img,right
#余韻を残すための関数
def lingering(imgs,frames):
img = imgs[-1]
for i in range(frames):
imgs.append(img)
#数式が徐々に現れる関数
def appearing(i,X,Y):
C = np.zeros(len(X)-1)
C[2*i+1:2*i+20] = np.arange(0.05,1.00,0.05)
C[2*i+20:] = 1
C = np.reshape(C,(len(X)-1,1))
img = ax2.pcolormesh(X,Y,C,cmap=cmap,zorder=10)
return img
#最初の1行目を表示する関数
def show_first_line(imgs,line):
i = 0
while True:
img,right = show_line(base+height/2,line)
X,Y = np.mgrid[-2:right+4:delta,height/2:3*height/2:height/2]
img += [appearing(i,X,Y)]
imgs.append(img)
i += 1
if 2*i+20 > len(X)-1:
break
#2行目を表示する関数
def show_second_line(imgs,line1,line2):
i = 0
while True:
img1,right1 = show_line(base+height/2,line1)
img2,right2 = show_line(base,line2)
img = img1 + img2
X,Y = np.mgrid[-2:right2+4:delta,0:height:height/2]
img += [appearing(i,X,Y)]
imgs.append(img)
i += 1
if 2*i+20 > len(X)-1:
break
#次の数式へと進む関数
def go_next_line(imgs,line1,line2):
for i in range(21):
alpha = max((10-i)/10,0)
img1,right1 = show_line(base+height/2+height*i/40,line1,alpha)
img2,right2 = show_line(base+height*i/40,line2)
img = img1 + img2
imgs.append(img)
#数式を読み込む関数
def load_script(imgs,lines):
N = len(lines)
show_first_line(imgs,lines[0])
for k in range(N-2):
show_second_line(imgs,lines[k],lines[k+1])
go_next_line(imgs,lines[k],lines[k+1])
show_second_line(imgs,lines[N-2],lines[N-1])
lingering(imgs,60)
#間のコメントの部分の関数
def interlude(imgs,str_comment):
N = len(str_comment)-1
for i in range(N):
for k in range(3):
interlude=fig.text(0.5,0.5,str_comment[:-N+i],
fontdict=commentdic,bbox=commentbgdic)
imgs.append([interlude])
lingering(imgs,20)
#上演
imgs=[]
load_script(imgs,lines_dx)
interlude(imgs,comment)
load_script(imgs,lines_dy)
mov=ani.ArtistAnimation(fig, imgs, 100)
plt.show()