問題文
同じ高さの直方体の形をした白いもちと赤いもちがあります。下図のように赤いもちの上に白いもちを重ねて立方体を作ります。
2点 $\mathrm{P,Q}$ はそれぞれ2辺 $\mathrm{AB,CD}$ 上の点で、 $$\mathrm{AP:PB}=4:3,\quad\mathrm{CQ}=\mathrm{QD}$$ です。3点 $\mathrm{P,Q,R}$ を通る平面で立方体を切断したとき、切り口の図形の白い部分と赤い部分の面積の比を、最も簡単な整数の比で答えなさい。
ただし、白いもちはどうのように切っても切り口の色は必ず白になり、赤いもちはどのように切っても切り口の色は必ず赤になります。
(2019 麻布中 3番)
$$22:19$$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
#紙の準備
fig = plt.figure()
ax=fig.add_subplot(projection='3d')
ax.set_title("2019麻布中算数 3番")
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax.set_zlim(0,1)
ax.set_box_aspect((1,1,1))
ax.axis("off")
#点の準備
pr = np.array([1,4/7,0])
rr = np.array([1,1,1])
qr = 1/2*pr+1/2*rr
ql = np.array([0,0,1/2])
rl = rr+(ql-qr)
pl = pr+8/11*(ql-qr)
#面の準備
w1roof = [rl,rr,(0,1,1)]
w1cut = [ql,qr,rr,rl]
w1side = [qr,(1,1,1/2),rr]
r1cut = [pl,pr,qr,ql]
r1side = [pr,(1,1,0),(1,1,1/2),qr]
r1front = [(0,0,0),pl,ql]
w2roof = [(0,0,1),(1,0,1),rr,rl]
w2side = [(1,0,1/2),qr,rr,(1,0,1)]
w2front = [ql,(1,0,1/2),(1,0,1),(0,0,1)]
r2side = [(1,0,0),pr,qr,(1,0,1/2)]
r2front = [pl,(1,0,0),(1,0,1/2),ql]
#色の準備
fw = (1,.9,.8)
fr = (1,.6,.5)
#残る方のモチ
poly1 = [w1roof,w1cut,w1side,r1cut,r1side,r1front]
fc1 = [fw,fw,fw,fr,fr,fr]
mochi1 = Poly3DCollection(poly1,facecolors=fc1)
ax.add_collection3d(mochi1)
#切られる方のモチ
poly2 = [w2roof,w2side,w2front,r2side,r2front]
fc2 = [fw,fw,fw,fr,fr]
mochi2 = Poly3DCollection(poly2,facecolors=fc2,clip_on=False)
ax.add_collection3d(mochi2)
#合同・相似の三角形たち
con1, = ax.plot([1,1,1,1],[1,1,11/14,1],[1,1/2,1/2,1],color=(.3,.6,.3),alpha=0,zorder=5)
con2, = ax.plot([0,0,0,0],[0,0,3/14,0],[1/2,1,1,1/2],color=(.3,.6,.3),alpha=0,zorder=5)
con3, = ax.plot([0,0,0,0],[0,0,-3/14,0],[0,1/2,0,0],color=(.3,.6,.3),alpha=0,zorder=5)
sim, = ax.plot([0,0,1,1,0],[0,-3/14,8/14,0,0],[0,0,0,0,0],color=(.6,.3,.3),alpha=0,zorder=5)
#フォント辞書たち
lendic={
"alpha" : 0,
"zorder" : 10,
"fontfamily" : "fantasy",
"verticalalignment" : "center",
"horizontalalignment" : "center",
}
circle={
"alpha" : 0,
"boxstyle" : "circle",
"facecolor" : "none",
"edgecolor" : (.6,.3,.3),
}
ansdic={
"alpha" : 0,
"fontsize" : 16,
"verticalalignment" : "center",
"horizontalalignment": "center",
}
commentdic={
"ha" : "center",
"va" : "center",
"size" : 20,
"color" : "white",
"zorder" : 10,
"visible" : False,
"fontfamily": "Meiryo",
"linespacing" : 2,
}
commentbgdic={
"facecolor" : "black",
"pad" : 300,
}
#一応、解説のつもりです
rr8=ax.text( 1.00, 0.40,-0.10, "8",color="0.4",fontdict=lendic)
rr6=ax.text( 1.00, 0.85,-0.10, "6",color="0.4",fontdict=lendic)
rr7=ax.text( 1.00, 1.10, 0.15, "7",color="0.4",fontdict=lendic)
rw7=ax.text( 1.00, 1.10, 0.65, "7",color="0.4",fontdict=lendic)
rb3=ax.text( 1.00, 0.90, 0.40, "3",color="0.4",fontdict=lendic)
lw3=ax.text( 0.00, 0.08, 1.05, "3",color=(.3,.6,.3),fontdict=lendic)
lw7=ax.text( 0.00,-0.08, 0.80, "7",color=(.3,.6,.3),fontdict=lendic)
lr7=ax.text( 0.00, 0.06, 0.15, "7",color=(.3,.6,.3),fontdict=lendic)
lr3=ax.text( 0.00,-0.10, 0.06, "3",color=(.3,.6,.3),fontdict=lendic)
cr3=ax.text( 0.20,-0.22, 0.00, "3",color=(.6,.3,.3),fontdict=lendic,bbox=circle)
cr8=ax.text( 0.72, 0.18, 0.00, "8",color=(.6,.3,.3),fontdict=lendic,bbox=circle)
cb1=ax.text( 0.48, 0.45, 0.55,"11",color=(.6,.3,.3),fontdict=lendic,bbox=circle)
cw1=ax.text( 0.43, 0.63, 1.05,"11",color=(.6,.3,.3),fontdict=lendic,bbox=circle)
cc1=fig.text(0.14, 0.08,"上の\n平行四辺形",color="w",fontdict=ansdic)
cc2=fig.text(0.25, 0.08,"$:$",fontdict=ansdic)
cc3=fig.text(0.35, 0.08,"下の\n 台形 ",color="w",fontdict=ansdic)
cc4=fig.text(0.62, 0.08,"$=(11+11):(11+8)$",fontdict=ansdic)
cc5=fig.text(0.88, 0.08,"$=22:19$",fontdict=ansdic)
ans=fig.text(0.50, 0.50,"(答)\n$22:19$",fontdict=commentdic,bbox=commentbgdic)
#お気に入りのイージング関数
def easing(x):
if x<0.5:
return 2*x**2
else:
return 1-(-2*x+2)**2/2
#おモチを切ります
def slide_mochi2(k):
newpoly = []
for poly in poly2:
X = np.array(poly).T[0]
Y = np.array(poly).T[1]
Z = np.array(poly).T[2]
Y = Y-k*3/7
Z = Z-k
newpoly.append(list(zip(X,Y,Z)))
mochi2.set_verts(newpoly)
#下ごしらえ
def prepare(i):
k1 = i/60
if k1<=1:
k = easing(k1)
ew = (1,.7,.1,k)
er = (1,.4,.4,k)
ec1 = [ew,ew,ew,er,er,er]
ec2 = [ew,ew,ew,er,er]
mochi1.set_edgecolor(ec1)
mochi2.set_edgecolor(ec2)
k2 = (i-60)/60
if k2<=1 and k2>=0:
k = easing(k2)
for txt in [rr8,rr6,rr7,rw7,rb3]:
txt.set_alpha(k)
#半分まで切ります
def slide1(i):
k1 = i/60
if k1==0:
rr8.set_alpha(0)
if k1<=1:
k = easing(k1)
slide_mochi2(k/2)
k2 = (i-60)/60
if k2<=1 and k2>=0:
k = easing(k2)
con1.set_alpha(k)
con2.set_alpha(k)
for txt in [lw3,lw7]:
txt.set_alpha(k)
for txt in [rw7,rb3]:
txt.set_color((.4-.1*k,.4+.2*k,.4-.1*k))
#さらに切り続けます
def slide2(i):
k1 = i/60
if k1<=1:
k = easing(k1)
slide_mochi2(k/2+1/2)
k2 = (i-60)/60
if k2<=1 and k2>=0:
k = easing(k2)
con3.set_alpha(k)
for txt in [lr7,lr3]:
txt.set_alpha(k)
k3 = (i-120)/60
if k3<=1 and k3>=0:
k = easing(k3)
sim.set_alpha(k)
lr3.set_color((.3+.3*k,.6-.3*k,.3))
rr8.set_color((.6,.3,.3))
rr8.set_alpha(k)
#完全に切り離します
def slide3(i):
k1 = i/60
if k1<=1:
k = easing(k1)
slide_mochi2(k+1)
k2 = (i-60)/60
if k2<=1 and k2>=0:
k = easing(k2)
circle["alpha"] = k
for txt in [cr3,cr8]:
txt.set_alpha(k)
txt.set_bbox(circle)
k3 = (i-90)/60
if k3<=1 and k3>=0:
k = easing(k3)
circle["alpha"] = k
cb1.set_alpha(k)
cb1.set_bbox(circle)
fwk = fw
frk = (1,.6-.2*k,.5-.1*k)
k4 = (i-120)/60
if k4<=1 and k4>=0:
k = easing(k4)
circle["alpha"] = k
cw1.set_alpha(k)
cw1.set_bbox(circle)
fwk = (1,.9-.2*k,.8-.7*k)
if k3>1:
frk = (1,.4,.4)
if k4<=1 and k3>=0:
mochi1.set_facecolors([fw,fwk,fw,frk,fr,fr])
#結論
def conclusion(i):
k1 = i/20
if k1<=1:
k = easing(k1)
cc1.set_alpha(k)
cc1.set_bbox(dict(boxstyle="round",fc=(1,.7,.1,k),ec="none"))
k2 = (i-20)/20
if k2<=1 and k2>=0:
k = easing(k2)
cc2.set_alpha(k)
k3 = (i-40)/20
if k3<=1 and k3>=0:
k = easing(k3)
cc3.set_alpha(k)
cc3.set_bbox(dict(boxstyle="round",fc=(1,.4,.4,k),ec="none"))
k4 = (i-60)/30
if k4<=1 and k4>=0:
k = easing(k4)
cc4.set_alpha(k)
k5 = (i-90)/30
if k5<=1 and k5>=0:
k = easing(k5)
cc5.set_alpha(k)
if i == 180:
ans.set_visible(True)
#台本
def update(t):
if t<150:
i = t
prepare(i)
elif t<300:
i = t-150
slide1(i)
elif t<510:
i = t-300
slide2(i)
elif t<720:
i = t-510
slide3(i)
else:
i = t-720
conclusion(i)
mov = ani.FuncAnimation(fig,update,950,interval=100)
plt.show()