理工系の数学 B の授業で,楕円の周長や面積,回転楕円体の表面積や体積を求めているので。
必要なモジュールの import
from sympy.abc import *
from sympy import *
# SymPy Plotting Backends (SPB)
from spb import *
# グラフを SVG で Notebook にインライン表示
%config InlineBackend.figure_formats = ['svg']
mathtext.fontset
の設定
# グラフを描くためではなくデフォルト設定のため
import matplotlib.pyplot as plt
plt.rcParams['mathtext.fontset'] = 'cm'
塗りつぶした楕円
SymPy Plotting Backends で長半径 $a$,単半径 $b$ の楕円を描く例。Ellipse()
を使ってみる。
a = 2
b = 1
alim = a+0.5
blim = b+0.5
p = plot_geometry(
Ellipse(Point(0, 0), hradius=a, vradius=b),
{"facecolor": "yellow", "edgecolor":"darkblue", "lw":3},
aspect = 'equal', size=(6.4, 4), n=400, show=False);
fig, ax = p.fig, p.ax
fig.tight_layout()
ax.grid(linestyle = 'dotted')
# 表示範囲
ax.set_xlim(-alim, alim)
ax.set_ylim(-blim, blim)
# 目盛設定
ax.set_xticks([-a, 0, a], ["$-a$", "$0$", "$a$"], fontsize=16)
ax.set_yticks([-b, 0, b], ["$-b$", "$0$", "$b$"], fontsize=16)
# x 軸,y 軸
ax.axhline(0, color='lightgray', dashes=(3, 3), linewidth=0.6)
ax.axvline(0, color='lightgray', dashes=(3, 3), linewidth=0.6);
塗りつぶし無しの楕円
p = plot_geometry(
Ellipse(Point(0, 0), hradius=a, vradius=b),
{"color":"darkblue", "lw":3}, is_filled=False,
aspect = 'equal', size=(6.4, 4), n=400, show=False);
fig, ax = p.fig, p.ax
fig.tight_layout()
ax.grid(linestyle = 'dotted')
# 表示範囲
ax.set_xlim(-alim, alim)
ax.set_ylim(-blim, blim)
# 目盛設定
ax.set_xticks([-a, 0, a], ["$-a$", "$0$", "$a$"], fontsize=16)
ax.set_yticks([-b, 0, b], ["$-b$", "$0$", "$b$"], fontsize=16)
# x 軸,y 軸
ax.axhline(0, color='lightgray', dashes=(3, 3), linewidth=0.6)
ax.axvline(0, color='lightgray', dashes=(3, 3), linewidth=0.6);
長軸の周りに回転した回転楕円体
\begin{eqnarray}
\frac{x^2}{a^2} + \frac{y^2}{b^2} &=& 1, \quad b \equiv a \sqrt{1-e^2}\\
\therefore\ \ y &=& b \sqrt{1-\frac{x^2}{a^2}} \equiv f(x)
\end{eqnarray}
$y = f(x)$ を $x$ の周りに回転してできる回転楕円体の表面を描く。まず,
def f(x):
return b*(sqrt(1-x**2/a**2))
$-a \leq x \leq a$ の範囲で $0 \leq y \leq f(x)$ の領域を塗りつぶして表示。
# 塗りつぶし部分
# plot_implicit は不等式で範囲指定できるが,
# 少し時間がかかる
p1 = plot_implicit(
(0 <= y) & (y <= f(x)), (x, -a, a), (y, -b, b),
adaptive=True, size=(6.4, 4),
aspect = 'equal',
# 塗りつぶしの色
color='lightblue', show = False
)
p2 = plot(
# y = f(x)
(f(x), (x, -a, a), {"color":"darkblue", "lw":3}),
# 長軸
(0, (x, -alim, alim), {"color":"blue", "lw":2}),
show = False)
p = (p1+p2)
fig, ax = p.fig, p.ax
fig.tight_layout()
# グリッドを点線で
ax.grid(linestyle = 'dotted')
# 表示範囲
ax.set_xlim(-alim, alim)
ax.set_ylim(-blim, blim)
# 目盛設定
ax.set_xticks([-a, 0, a], ["$-a$", "$0$", "$a$"], fontsize=16)
ax.set_yticks([-b, 0, b], ["$-b$", "$0$", "$b$"], fontsize=16)
ax.set_xlabel("")
ax.set_ylabel("")
# x 軸,y 軸
ax.axhline(0, color='lightgray', dashes=(3, 3), linewidth=0.6)
ax.axvline(0, color='lightgray', dashes=(3, 3), linewidth=0.6);
# 凡例を非表示に
ax.get_legend().set_visible(False);
$y = f(x)$ を $x$ 軸の周りに $\theta$ だけ回転させると,
\begin{eqnarray}
x &=& x \\
y &=& f(x) \cos\theta \\
z &=& f(x) \sin\theta
\end{eqnarray}
となることに留意。
# 回転楕円体の表面
p1 = plot3d_parametric_surface(
x, f(x)*cos(t), f(x)*sin(t), (x, -a, a), (t, 0, 2*pi),
{'cmap':'Blues', 'lw':0.5, 'edgecolor':'lightblue'},
use_cm=True, color_func=f(x)*cos(t), colorbar=False,
axis=False, size=(6.4, 6.4), n=40,
xlim=(-alim,alim), ylim=(-blim, blim), zlim=(-blim, blim),
aspect="equal", show=False
);
p2 = plot3d_parametric_line(
# x 軸
(x, 0, 0, (x, -alim, a), "", {"color":"blue","zorder":0, "lw":2}),
(x, 0, 0, (x, a, alim), "", {"color":"blue","zorder":10,"lw":2}),
# z = z(x)
(x, 0, f(x), (x, -a, -a+0.1), "", {"color":"darkblue","zorder":0, "lw":3}),
(x, 0, f(x), (x, -a+0.1, a), "", {"color":"darkblue","zorder":10,"lw":3}),
use_cm=False, show=False
)
(p1+p2).show();
短軸の周りに回転した回転楕円体
$\displaystyle x = a \sqrt{1-\frac{y^2}{b^2}} \equiv g(y)$ を $y$ の周りに回転してできる回転楕円体の表面。
def g(y):
return a*(sqrt(1-y**2/b**2))
$-b \leq y \leq b$ の範囲で $0 \leq x \leq g(y)$ の領域を塗りつぶして表示。
# 塗りつぶし部分
p1 = plot_implicit(
(0 <= x) & (x <= g(y)), (x, 0, a), (y, -b, b),
adaptive=True, size=(6.4, 4),
aspect = 'equal',
# 塗りつぶしの色
color='lightpink', show = False
)
p2 = plot_parametric(
# x = g(y)
(g(y), y, (y, -b, b), {"color":"darkred", "lw":3}),
# 短軸
(0, y, (y, -blim, blim), {"color":"red", "lw":2}),
use_cm=False, show = False)
p = (p1+p2)
fig, ax = p.fig, p.ax
fig.tight_layout()
ax.grid(linestyle = 'dotted')
# 表示範囲
ax.set_xlim(-alim, alim)
ax.set_ylim(-blim, blim)
# 目盛設定
ax.set_xticks([-a, 0, a], ["$-a$", "$0$", "$a$"], fontsize=16)
ax.set_yticks([-b, 0, b], ["$-b$", "$0$", "$b$"], fontsize=16)
ax.set_xlabel("")
ax.set_ylabel("")
# x 軸,y 軸
ax.axhline(0, color='lightgray', dashes=(3, 3), linewidth=0.6)
ax.axvline(0, color='lightgray', dashes=(3, 3), linewidth=0.6);
# 凡例を非表示に
ax.get_legend().set_visible(False);
$x = g(z)$ を $z$ 軸の周りに $\theta$ だけ回転させると,
\begin{eqnarray}
x &=& g(z) \cos\theta \\
y &=& g(z) \sin\theta \\
z &=& z
\end{eqnarray}
となることに留意する。
# 回転楕円体の表面
p1 = plot3d_parametric_surface(
g(z)*cos(t), g(z)*sin(t), z, (z, -b, b), (t, 0, 2*pi),
{'cmap':'Reds', 'lw':0.5, 'edgecolor':'pink'},
use_cm=True, color_func=g(z)*sin(t), colorbar=False,
axis=False, size=(6.4, 6.4), n=80,
xlim=(-2.2,2.2), ylim=(-2.2, 2.2), zlim=(-1.2,1.2),
aspect="equal", show=False
)
p2 = plot3d_parametric_line(
# z 軸
(0, 0, z, (z, -2, b), "", {"color":"red","zorder":0, "lw":2}),
(0, 0, z, (z, b, 2), "", {"color":"red","zorder":10,"lw":2}),
# x = g(z)
(g(z), 0, z, (z, -2, -0.5), "", {"color":"darkred","zorder":0,"lw":3}),
(g(z), 0, z, (z, -0.5, b), "", {"color":"darkred","zorder":10,"lw":3}),
use_cm=False, show=False
)
(p1+p2).show();