問題文
いくつかの半径 $3$ の円を、半径 $2$ の円 $Q$ に外接し、かつ、互いに交わらないように配置する。このとき、次の問いに答えよ。
- 半径 $3$ の円の1つを $R$ とする。円 $Q$ の中心を端点とし、円 $R$ に接する2本の半直線のなす角を $\theta$ とおく。ただし、 $0 \lt \theta \lt \pi$ とする。このとき、 $\sin\theta$ を求めよ。
- $\frac{\pi}{3} \lt \theta \lt \frac{\pi}{2}$ を示せ。
- 配置できる半径 $3$ の円の最大個数を求めよ。
(2008 九州大学 理系第5問)
- $\frac{24}{25}$
- 略
- $4$ 個
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib.patches as patches
#紙の準備
fig = plt.figure()
fig.suptitle("2008九大数学 理系第5問",
color="0.5",ha="right",x=0.96,y=0.96)
ax = fig.add_subplot(111)
ax.set_xlim(-9,9)
ax.set_ylim(-9,9)
ax.set_aspect("equal")
ax.axis("off")
#真ん中の円
c0 = patches.Circle((0,0),radius=2,fc="orangered")
#周りの円
cs = []
for i in range(5):
alpha = np.pi/2 - i*np.arcsin(24/25)
c = patches.Circle((5*np.cos(alpha),5*np.sin(alpha)),radius=3,
fc=(0.8-0.05*i,0.8,0),alpha=0)
cs.append(c)
#円を描きます
for c in [c0]+cs:
ax.add_patch(c)
#「アウト」を書きます
arrow_dict = dict(arrowstyle="-|>",
connectionstyle="angle3,angleA=0,angleB=-60",
linewidth=2.0,color="r",alpha=0)
out = ax.annotate("アウト!",xy=(-3.0,4.7),xytext=(-12,7.5),
size=16,color="r",fontfamily="HGSoeiKakupoptai",
arrowprops=arrow_dict,alpha=0)
#減らずグチたち
phrasedic={
"ha" : "center",
"va" : "center",
"size" : 20,
"color" : "white",
"zorder" : 100,
"visible" : False,
"linespacing": 2.4,
"fontfamily": "Meiryo",
}
phrases = []
phrases.append("""
半径2の円の周りに
半径3の円は
最大何個まで置けるのか?
""")
phrases.append("""
レッツ、検証!
""")
phrases.append("""
5個目で重なります
""")
phrases.append("""
というわけで
4個まで置けました
""")
phrases.append("""
END
""")
seq_prs = []
for i in range(len(phrases)):
prs = fig.text(0.5,0.5,"\n",fontdict=phrasedic,
bbox=dict(color="black",pad=300))
seq_prs.append(prs)
#お気に入りのイージング関数
def easing(x):
if x<0.5:
return 2*x**2
elif x<1:
return 1-(-2*x+2)**2/2
else:
return 1
#オブジェクトを徐々に表示する関数
def show_obj(k,obj):
alpha = easing(k/39)
obj.set_alpha(alpha)
#セクションを判定する関数
def section(i):
n = np.argmin(~(i<endings))
keys = list(periods.keys())
key = keys[n]
if n == 0:
k = i
previous_key = None
else:
k = i-endings[n-1]
previous_key = keys[n-1]
return k,key,previous_key
#台本の構成
periods = {"P1":140,"P2":60,"S1":20,
"C1":40,"C2":40,"C3":40,"C4":40,"C5":40,"O1":100,
"P3":40,"P4":120,"P5":40}
endings = np.cumsum(list(periods.values()))
#上演
def update(i):
k,key,previous_key = section(i)
#台本のキーには必ず数字をつけます
index = int(key[1])-1
if "C" in key:
show_obj(k,cs[index])
elif "P" in key:
phrase = phrases[index]
end = min(k//3+2,len(phrase)-1)
seq_prs[index].set_text(phrase[1:end])
elif "O" in key:
show_obj(k,out)
show_obj(k,out.arrow_patch)
if k == 0:
if "P" in key:
seq_prs[index-1].set_visible(False)
seq_prs[index].set_visible(True)
elif "P" in previous_key:
seq_prs[int(previous_key[1])-1].set_visible(False)
mov = ani.FuncAnimation(fig,update,endings[-1],interval=50)
plt.show()