問題文
図のように、半径が $2\mathrm{cm}$ の大きな円の周上に中心を持つ、半径が $1\mathrm{cm}$ の小さな円が7つあります。また、小さな円の中心はその隣の小さな円の周上にあります。このとき、太線の長さは $\mathrm{cm}$ です。(2023 灘中 1日目9番)
$$18.84$$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from matplotlib.patches import Circle,Arc,Path
#紙の準備
fig = plt.figure()
fig.suptitle("2023灘中 1日目9番",
color="0.6",ha="right",x=0.96,y=0.08)
fig.subplots_adjust(top=0.90,bottom=0.15)
ax = fig.add_subplot(111)
ax.set_xlim(-3.1,3.1)
ax.set_ylim(-3.1,3.1)
ax.set_aspect("equal")
ax.axis("off")
#ひもの色と太さ
color = "royalblue"
width = 3
#中央の大円と解説を準備
ax.add_patch(Circle((0,0),2,ec="0.8",fill=False))
O, = ax.plot(0,0,alpha=0,color="0.8",marker="o")
dx = np.linspace(-3,3,100)
dy = -(dx-3)*(dx+3)/20
d1,= ax.plot(dx,np.zeros_like(dx),zorder=-10,
alpha=0,color="0.8",linewidth=1,linestyle="dashed")
d2,= ax.plot(dx,dy,zorder=-10,
alpha=0,color="0.6",linewidth=1)
txt0 = ax.text(0.0,-1.0,"青いひもの長さは?",color="navy",ha="center")
txt1 = ax.text(0.0, 0.3,"直径\n$6$",alpha=0,color="0.2",ha="center",
bbox=dict(facecolor="white",linewidth=0),visible=False)
txt2 = ax.text(0.2,-0.6,"ひもの長さは",alpha=0,color="0.2",ha="right")
txt3 = ax.text(0.4,-0.6,"$6\\mathcal{\\pi}$",alpha=0,color="0.2",fontsize=18)
#7個の小円を描きます
beta = 2*np.arcsin(1/4)
gamma = np.linspace(-3*beta,3*beta,7)
Ox = 2*np.cos(gamma+np.pi/2)
Oy = 2*np.sin(gamma+np.pi/2)
circles = []
for i in range(7):
c = Circle((Ox[i],Oy[i]),1,ec="0.8",fill=False)
circles.append(c)
ax.add_patch(c)
#ひもを描きます
thu1 = np.rad2deg(gamma-beta/2)-30+90
thu2 = np.rad2deg(gamma+beta/2)+30+90
thd1 = thu2-240
thd2 = thu1-120
aus = []
ads = []
for i in range(1,6):
au = Arc((Ox[i],Oy[i]),2,2,theta1=thu1[i],theta2=thu2[i],
color=color,linewidth=width,capstyle="round")
ad = Arc((Ox[i],Oy[i]),2,2,theta1=thd1[i],theta2=thd2[i],
color=color,linewidth=width,capstyle="round")
aus.append(au)
ads.append(ad)
ax.add_patch(au)
ax.add_patch(ad)
#ひもの端っこを閉じます
a0 = Arc((Ox[0],Oy[0]),2,2,theta1=thd1[0],theta2=thu2[0],
color=color,linewidth=width,capstyle="round")
ax.add_patch(a0)
a6 = Arc((Ox[6],Oy[6]),2,2,theta1=thu1[6],theta2=thd2[6],
color=color,linewidth=width,capstyle="round")
ax.add_patch(a6)
#小円の更新用関数
def update_circles(r,beta):
gamma = np.linspace(-3*beta,3*beta,7)
Ox = (3-r)*np.cos(gamma+np.pi/2)
Oy = (3-r)*np.sin(gamma+np.pi/2)
for i in range(7):
circles[i].set_center((Ox[i],Oy[i]))
circles[i].set_radius(r)
return gamma,Ox,Oy
#弧の更新用関数
def update_arc(a,r,Ox,Oy,th1,th2):
a.set_center((Ox,Oy))
a.set_width(2*r)
a.set_height(2*r)
a.theta1 = th1
a.theta2 = th2
a._path = Path.arc(a.theta1,a.theta2)
#ひもの更新用関数
def update_arcs(arcs,r,Ox,Oy,th1,th2):
for i in range(5):
update_arc(arcs[i],r,Ox[i+1],Oy[i+1],th1[i+1],th2[i+1])
#お気に入りのイージング関数
def easing(x):
if x<0.5:
return 2*x**2
else:
return 1-(-2*x+2)**2/2
#解説を表示する関数
def show_objs(t,end,objs):
start = end-40
if t>=start and t<end:
k = easing((t-start)/39)
for obj in objs:
obj.set_alpha(k)
#台本
def update(t):
if t<40:
pass
elif t<50:
k = easing((t-40)/9)
txt0.set_alpha(1-k)
elif t<150:
k = easing((t-50)/99)
r = 1+0.5*k
beta = 2*np.arcsin(r*np.sin((1/4/r-1/12)*np.pi)/(3-r))
gamma,Ox,Oy = update_circles(r,beta)
thu1 = np.rad2deg(gamma-beta/2)-(45/r-15)+90
thu2 = np.rad2deg(gamma+beta/2)+(45/r-15)+90
thd1 = thu2-(150+90/r)
thd2 = thu1-(210-90/r)
update_arcs(aus,r,Ox,Oy,thu1,thu2)
update_arcs(ads,r,Ox,Oy,thd1,thd2)
update_arc(a0,r,Ox[0],Oy[0],thd1[0],thu2[0])
update_arc(a6,r,Ox[6],Oy[6],thu1[6],thd2[6])
elif t<250:
k = easing((t-150)/99)
r = 1.5
beta = (1+k)*np.pi/6
gamma,Ox,Oy = update_circles(r,beta)
thu1 = np.rad2deg(gamma-beta)+90
thu2 = np.rad2deg(gamma+beta)+90
update_arcs(aus,r,Ox,Oy,thu1,thu2)
update_arc(a0,r,Ox[0],Oy[0],thu1[0]-360+np.rad2deg(7*beta),thu2[0])
update_arc(a6,r,Ox[6],Oy[6],thu1[6],thu2[6]+360-np.rad2deg(7*beta))
elif t<350:
k = easing((t-250)/99)
r = 1.5+1.5*k
beta = np.pi/3
gamma,Ox,Oy = update_circles(r,beta)
thu1 = np.rad2deg(gamma)-90/r+90
thu2 = np.rad2deg(gamma)+90/r+90
update_arcs(aus,r,Ox,Oy,thu1,thu2)
update_arc(a0,r,Ox[0],Oy[0],thu1[0]+90/r,thu2[0])
update_arc(a6,r,Ox[6],Oy[6],thu1[6],thu2[6]-90/r)
elif t==400:
txt1.set_visible(True)
else:
show_objs(t,400,[O,d1])
show_objs(t,450,[d2,txt1])
show_objs(t,500,[txt2])
show_objs(t,550,[txt3])
mov = ani.FuncAnimation(fig,update,600,interval=50)
plt.show()