漢字プリント 数学プリント
問題文
不等式 $$1 \leqq ||x|-2|+||y|-2| \leqq 3$$ の表す領域を $xy$ 平面上に図示せよ。
(2013 大阪大学 理系第2問)
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani

#紙の準備
fig = plt.figure()
fig.suptitle("2013阪大数学 理系第2問",y=0.9)
ax1 = fig.add_subplot(121)
ax1.set_xlim(-6,6)
ax1.set_ylim(-6,6)
ax1.set_xticks([-4,-2,0,2,4])
ax1.set_yticks([-4,-2,0,2,4])
ax1.set_aspect("equal")
ax1.grid()
ax2 = fig.add_subplot(122)
ax2.set_xlim(0,1)
ax2.set_ylim(0,1)
ax2.set_aspect("equal")
ax2.axis("off")
plt.rcParams["mathtext.fontset"] = 'cm'

#変数の準備
x = np.linspace(-6,6,13)
y = np.linspace(-6,6,13)
X,Y = np.meshgrid(x,y)
#領域の方程式たち
F=[
(X-2)+(Y-2),
abs(X-2)+(Y-2),
abs(X-2)+abs(Y-2),
abs(abs(X)-2)+abs(Y-2),
abs(abs(X)-2)+abs(abs(Y)-2)
]
#折り目たち
fold=[
"vline(2",
"hline(2",
"vline(0",
"hline(0",
]
#数式たち
latex=[
"x+y",
"(x-2)+(y-2)",
"|x-2|+(y-2)",
"|x-2|+|y-2|",
"||x|-2|+|y-2|",
"||x|-2|+||y|-2|",
]

#セリフたち
comment0="""\
$1\\;\\leqq\\;||x|-2|+||y|-2|\\;\\leqq\\;3$

を図示せよ
"""
comment1="""\
△▼△▼△▼△▼△▼△▼△▼△
▼△▼△▼△▼△▼△▼△▼△▼

折り紙職人になりましょう

△▼△▼△▼△▼△▼△▼△▼△
▼△▼△▼△▼△▼△▼△▼△▼
"""

#セリフを挿入する関数
def interlude(imgs,str_comment,frames):
    
    fdic_wc={
        "ha" : "center",
        "va" : "center",
        "color" : "white",
        "animated" : True,
        "fontsize" : 20,
        "fontfamily": "Meiryo",
        }
    boxdic={
        "facecolor" : "black",
        "pad" : 300,
        }
    
    for i in range(frames):
        interlude=fig.text(0.5,0.5,str_comment,
                          fontdict=fdic_wc,bbox=boxdic)
        imgs.append([interlude])

#数式を表示させる関数
def show_latex(img,i,alpha):
    
    for k in range(len(latex)):
        if k==i:
            col1 = 0.7*alpha*np.ones(3)
            col2 = "0.0"
        elif k==i+1:
            col1 = 0.7*(1-alpha)*np.ones(3)
            col2 = "0.8"
        else:
            col1 = "0.7"
            col2 = "0.8"
            
        img+=[ax2.text(0.5,1-(k+0.8)/len(latex),
                       "$1\\;\\leqq\\;"+latex[k]+"\\;\\leqq\\;3$",
                       fontsize=14,ha="center",color=col1)]
        img+= ax2.plot(0.5,1-(k+1.2)/len(latex),
                       markersize=6,marker="v",color=col2)

#はじめに
def start(imgs):
    
    N = 50
    for j in range(N):
        
        R = ax1.contourf(X,Y,F[0],[-3,-1],colors=[(1,0,0)])
        img = R.collections
        
        show_latex(img,0,0)
        img+= ax2.plot(0.5,1-(1.2)/len(latex),
                       markersize=6,marker="v",color="0.8")
        imgs.append(img)

#途中の進化
def transition(imgs):
    
    for i in range(len(F)):
    
        N = 101
        for j in range(N):
            
            alpha = 1/(1+np.exp(-0.5*(j-(N-1)/2)))
            
            if i == 0:
                R = ax1.contourf(X,Y,F[i],[-3+4*alpha,-1+4*alpha],colors=[(1,0,0)])
                img = R.collections
                img += [ax1.annotate("",xy=(3,3),xytext=(1,1),arrowprops=dict(color="darksalmon",arrowstyle="fancy"))]
            else:
                R1 = ax1.contourf(X,Y,F[i-1],[1,3],colors=[(1,0,0,1-alpha)])
                R2 = ax1.contourf(X,Y,F[i],[1,3],colors=[(1,0,0,alpha)])
                img = R1.collections + R2.collections
                img += eval('[ax1.ax'+fold[i-1]+',color="darksalmon",linestyle="--",linewidth=2)]')
            
            show_latex(img,i,alpha)
            imgs.append(img)

#おわりに
def end(imgs):
    
    N = 70
    for j in range(N):
        
        R = ax1.contourf(X,Y,F[-1],[1,3],colors=[(1,0,0)])
        img = R.collections
        
        show_latex(img,len(F),0)
        imgs.append(img)

#上演
imgs=[]
interlude(imgs,comment0,60)
interlude(imgs,comment1,40)
start(imgs)
transition(imgs)
end(imgs)

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