問題文
$|\,x\,| \leqq 2$ を満たす複素数 $x$ と、 $|\,y-(8+6i)\,| = 3$ を満たす複素数 $y$ に対して、 $z = \dfrac{x+y}{2}$ とする。このような複素数 $z$ が複素数平面において動く領域を図示し、その面積を求めよ。(2024 京都大学 理系第2問)
$$6\pi$$
※ この答えは学校側が公表したものではありません。個人が作成した非公式の答えです。
コード
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from matplotlib.patches import Circle,FancyArrowPatch
#座標の描画
fig = plt.figure()
fig.suptitle("2024京大数学 理系第2問",
x=0.96,y=0.96,color="0.7",ha="right")
ax = fig.add_subplot(111)
ax.set_xlim(-3,12)
ax.set_ylim(-3,10)
ax.set_aspect("equal")
ax.axis("off")
jk = ax.plot(12,0,">",0,10,"^",
[-4,12],[0,0],"-",
[0,0],[-4,10],"-",
c="0.8",clip_on=False)
#円の表記クラス
class en_hyouki:
def __init__(self,x,y,alpha=1):
self.x,self.y,self.alpha = x,y,alpha
self.hk = ax.plot(x,y,".",
[x,x],[0,y],"--",
[0,x],[y,y],"--",
c="0.8",ms=8,alpha=alpha)
self.hk += [ax.text(x,-0.6,str(x),c="0.6",ha="center",alpha=alpha)]
self.hk += [ax.text(-0.5,y,str(y),c="0.6",va="center",alpha=alpha)]
def hankei(self,r):
arr = FancyArrowPatch((self.x-.1,self.y-.1),
(self.x+r/np.sqrt(2)+.1,self.y+r/np.sqrt(2)+.1),
arrowstyle='<->',mutation_scale=8,
ec="0.5",zorder=10,alpha=self.alpha)
ax.add_patch(arr)
arr = [arr,ax.text(self.x+r/np.sqrt(2)/2,self.y+r/np.sqrt(2)/2-0.5,str(r),
c="0.4",zorder=10,alpha=self.alpha)]
return arr
def hankei2(self,r):
arr = FancyArrowPatch((self.x+.1,self.y+.1),
(self.x-r/np.sqrt(2)-.1,self.y-r/np.sqrt(2)-.1),
arrowstyle='<->',mutation_scale=7,
ec="0.5",zorder=10,alpha=self.alpha)
ax.add_patch(arr)
arr = [arr,ax.text(self.x-1.2,self.y-0.9,str(r),
c="0.4",zorder=10,alpha=self.alpha)]
return arr
#円まわりの表記を描画
en1 = en_hyouki(8,6)
en1.hk += en1.hankei(3)
en1.hk += [ax.text(2.2,-0.6,"2",c="0.6")]
en1.hk += [ax.text(-0.5,2.3,"2",c="0.6")]
en2 = en_hyouki(4,3,alpha=0)
en2R = en2.hankei(2.5)
en2r = en2.hankei2(0.5)
#円たちを描画
Cdic = dict(fill=False,lw=4,ec="0.8")
C1 = Circle((0,0),2,**Cdic)
C2 = Circle((8,6),3,**Cdic)
C3 = Circle((4,3),2.5,**Cdic,alpha=0)
C4 = Circle((4,3),0.5,**Cdic,alpha=0)
for obj in [C1,C2,C3,C4]:
ax.add_patch(obj)
#動く点と軌跡を準備
cl,cx,cy,cz = "lightsteelblue","darkolivegreen","deepskyblue","darkcyan"
L = ax.plot([0,8],[2,9],c=cl,lw=4,alpha=0)
Pdic = dict(marker="o",ms=8,alpha=0)
P = ax.plot(0,2,cx,8,9,cy,4,5.5,cz,**Pdic)
Tdic = dict(alpha=0.2,lw=7,solid_capstyle="round")
T = ax.plot(0,2,cx,8,9,cy,4,5.5,cz,**Tdic)
#イージング関数
def easing(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 nurinuri(a,f,r):
x = np.array([[-r(a)*np.sin(2*f*np.pi*a)],[r(a)*np.cos(2*f*np.pi*a)]])
y = np.array([[8-3*np.sin(2*f*np.pi*a)],[6+3*np.cos(2*f*np.pi*a)]])
z = (x+y)/2
L[0].set_data(np.block([x,y]))
for i,v in enumerate([x,y,z]):
P[i].set_data(v)
oldT = np.array(T[i].get_data())
newT = np.block([oldT,v])
T[i].set_data(newT)
#司会役クラス
class Sikai:
def __init__(self,clips):
self.verbs = []
self.objects = []
self.periods = []
for clip in clips:
self.verbs.append(clip[:-1:2])
self.objects.append(clip[1::2])
self.periods.append(clip[-1])
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 = (i-self.endings[p]+1)/self.periods[p]
return V,X,a
#台本
clips = [
("P",[],20),
("A",L+P,"D",jk+en1.hk,30),
("N",(1,lambda a: 2),40),
("N",(0,lambda a: 2*(1-2*a)),"D",[C1,C2],20),
("N",(1,lambda a: -2),40),
("N",(1,lambda a: -2*np.cos(80*np.pi*a)),500),
("D",L+P,"D2",T[:-1],30),
("A",jk+en2.hk+[C3,C4],30),
("A",en2R,20),
("A",en2r,20),
("P",[],60),
]
#司会役の手配
sk = Sikai(clips)
#上演
def update(i):
V,X,a = sk.section(i)
for v,x in zip(V,X):
if v=="A":
for obj in x:
obj.set_alpha(easing(a))
elif v=="D":
for obj in x:
obj.set_alpha(easing(1-a))
elif v=="D2":
for obj in x:
obj.set_alpha(0.2*easing(1-a))
elif v=="N":
nurinuri(a,x[0],x[1])
#ラスト2秒に挿入
if i == sk.T-20:
fig.text(0.5,0.5,"面積は自分で \n 計算してね ♡",
c="w",size=20,linespacing=2,ha="center",va="center",
bbox=dict(color="black",pad=300))
mov = ani.FuncAnimation(fig,update,sk.T,interval=100)
plt.show()