漢字プリント 数学プリント
問題文
ある立体の展開図は図のようになっています。この立体の体積は    $\mathrm{cm^3}$ です。ただし、同じ記号がかかれた辺の長さは等しいとします。
図
(2024 灘中 1日目12番)
$$13.5$$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from scipy.spatial.transform import Rotation
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

#紙の準備
fig = plt.figure()
fig.suptitle("2024灘中算数 1日目12番",
             color="0.7",ha="right",x=0.96,y=0.96)
fig.subplots_adjust(left=0,right=0.985,bottom=0.18)
ax = fig.add_subplot(projection='3d',computed_zorder=False)
ax.view0 = (90,-90)
ax.view_init(*ax.view0)
ax.set_box_aspect((1,1,1))
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
ax.set_zlim(0,2)
ax.axis("off")

#折れる面クラス
class Men:
    
    rot1 = -np.arccos(-1/np.sqrt(3))*np.array([1/2,np.sqrt(3)/2,0])
    fix1 = np.array([-3/4,np.sqrt(3)/4,0])
    
    def __init__(self,verts,fc=(0.7,0.3,0,0.2),ec=(0.5,0.5,0.5)):
        self.verts = []
        for vert in verts:
            self.verts.append(vert+(0,))
        self.poly  = Poly3DCollection([self.verts],clip_on=False,fc=fc,ec=ec)
        ax.add_collection3d(self.poly)
        self.R1verts = self.fold(self.verts,self.rot1,self.fix1)
        
    def fold(self,verts,rotvec,fixpoint):
        R = Rotation.from_rotvec(rotvec)
        Rverts = []
        for i,vert in enumerate(verts):
            Rvert = R.apply(np.array(vert)-fixpoint)+fixpoint
            Rverts.append(Rvert)
        return Rverts
    
    def fold1(self,a):
        Rverts = self.fold(self.verts,a*self.rot1,self.fix1)
        self.poly.set_verts([Rverts])
        
    def fold2(self,a,p2):
        f1 = self.R1verts[0]
        f2 = self.R1verts[len(self.verts)-4]
        fix = (f1+f2)/2
        p1 = self.R1verts[-2]-fix
        p2 = p2-fix
        theta = np.arccos(np.dot(p1,p2)/np.linalg.norm(p1)/np.linalg.norm(p2))
        rot = theta*(f1-f2)/np.linalg.norm(f1-f2)
        Rverts = self.fold(self.R1verts,a*rot,fix)
        self.poly.set_verts([Rverts])

#面たち、その1
hex0 = Men([(
    np.cos(i*np.pi/3),
    np.sin(i*np.pi/3))
    for i in range(6)],fc=(0,0.7,0.3,0.2),ec=None)
tri1 = Men([(
    np.cos(i*np.pi/2)/2,
    np.sin(i*np.pi/2)/2+np.sqrt(3)/2)
    for i in range(3)])
tri2 = Men([(
    np.cos((i/2-2/3)*np.pi)/2+3/4,
    np.sin((i/2-2/3)*np.pi)/2-np.sqrt(3)/4)
    for i in range(3)])
tri3 = Men([(
    np.cos((i/2+2/3)*np.pi)/2-3/4,
    np.sin((i/2+2/3)*np.pi)/2-np.sqrt(3)/4)
    for i in range(3)])
pnt1 = Men([(
    np.cos(i*np.pi/3),
    np.sin(i*np.pi/3))
    for i in range(4,6)]+[(
    np.cos((-i/2)*np.pi),
    np.sin((-i/2)*np.pi)-(np.sqrt(3)+1)/2)
    for i in range(3)])
pnt2 = Men([(
    np.cos(i*np.pi/3),
    np.sin(i*np.pi/3))
    for i in range(2,4)]+[(
    np.cos((-i/2+4/3)*np.pi)-(3+np.sqrt(3))/4,
    np.sin((-i/2+4/3)*np.pi)+(np.sqrt(3)+1)/4)
    for i in range(3)])
pnt3 = Men([(
    np.cos(i*np.pi/3),
    np.sin(i*np.pi/3))
    for i in range(0,2)]+[(
    np.cos((-i/2+2/3)*np.pi)+(3+np.sqrt(3))/4,
    np.sin((-i/2+2/3)*np.pi)+(np.sqrt(3)+1)/4)
    for i in range(3)])

#面たち、その2
P = np.array([(
    np.cos((i/2-1/6)*np.pi)-(3+np.sqrt(3))/4,
    np.sin((i/2-1/6)*np.pi)+(np.sqrt(3)+1)/4,
    np.sqrt(2)*(1-i//4)) for i in range(5)])
pnt456 = Poly3DCollection([
    [hex0.R1verts[5],hex0.R1verts[0],P[1],P[0],P[3]],
    [hex0.R1verts[1],hex0.R1verts[2],P[4],P[0],P[1]],
    [hex0.R1verts[3],hex0.R1verts[4],P[3],P[0],P[4]]
    ],fc=(1,1,1,0),clip_on=False)
ax.add_collection3d(pnt456)

#文字たち
tdic = dict(ha="center",va="center",color="0.3",
            size=16,fontfamily="HGSoeiKakupoptai")
txt1 = fig.text(-1,0.28,"立方体の",**tdic)
txt2 = fig.text(-1,0.20,"ジャスト",**tdic)
txt3 = fig.text(-1,0.12,"半分や!",**tdic)

#司会役クラス
class Sikai:
    
    def easing(self,x):
        if x<0.0:
            return 0
        elif x<0.5:
            return 2*x**2
        elif x<1.0:
            return 1-(-2*x+2)**2/2
        else:
            return 1
    
    def __init__(self,clips):
        self.verbs = []
        self.objects = []
        self.periods = []
        for clip in clips:
            self.verbs.append(clip[0])
            self.objects.append(clip[1])
            self.periods.append(clip[2])
        endings = np.cumsum(self.periods)
        self.endings = np.append(0,endings)
        self.T = self.endings[-1]
    
    def section(self,i):
        p = np.argmin(~(i<self.endings[1:]))
        v = self.verbs[p]
        x = self.objects[p]
        a = self.easing((i-self.endings[p])/(self.periods[p]-1))
        return v,x,a

#台本
clips = [
    ("P",[],20),
    ("V",(35,-90),30),
    ("F1",[],40),
    ("V",(35,-105),15),
    ("F2",(tri3,pnt2.verts[2]),15),
    ("V",(35,-195),30),
    ("F2",(pnt1,pnt2.verts[3]),30),
    ("V",(35,-210),15),
    ("F2",(tri2,P[2]),15),
    ("V",(35,-225),15),
    ("F2",(pnt3,pnt2.verts[3]),30),
    ("V",(35,-315),30),
    ("F2",(tri1,pnt2.verts[4]),15),
    ("V",(35,-405),30),
    ("A1",[],40),
    ("A2",[],10),
    ("A3",(txt1,-0.55),10),
    ("A3",(txt2,-0.50),10),
    ("A3",(txt3,-0.45),10),
    ("P",[],20)]

#司会役の手配
sk = Sikai(clips)

#上演
def update(i):
    
    v,x,a = sk.section(i)
    
    if v == "V":
        elev = a*x[0] + (1-a)*ax.view0[0]
        azim = a*x[1] + (1-a)*ax.view0[1]
        ax.view_init(elev,azim)
        if a==1:
            ax.view0 = x
            
    elif v == "F1":
        for obj in [hex0,tri1,tri2,tri3,pnt1,pnt3]:
            obj.fold1(a)
        new_x = -a*(3+np.sqrt(3))/4
        new_y =  a*(np.sqrt(3)+1)/4
        ax.set_xlim(new_x-1,new_x+1)
        ax.set_ylim(new_y-1,new_y+1)
        
    elif v == "F2":
        x[0].fold2(a,x[1])
        
    elif v == "A1":
        pnt456.set_facecolor((0.3,0.7,0,0.2*a))
        pnt456.set_edgecolor((0.5,0.5,0.5,0.5*a))
        
    elif v == "A2":
        ax.set_zlim(-0.8*a,2-0.8*a)
        
    elif v == "A3":
        x[0].set_x(x[1]+a)

#上演
mov = ani.FuncAnimation(fig,update,sk.T,interval=100)
plt.show()
解説になっているのか?甚だギモンな動画
「高校数学のエアポケット」に戻る