対称移動
前回記事で、あらゆる種類の線型変換は行列形式で表現できることを解説しました。中でも 鏡映変換 (反転・折り返し) は基本的な線型変換です。
軸に関する鏡映変換
任意の点を $x$ 軸に関して折り返す表現行列は
\[A=\begin{bmatrix}1&0\\0&-1\\\end{bmatrix}\tag{1}\]
で与えられます。実際、行列 $A$ によって、ベクトル $\boldsymbol{r}=\begin{bmatrix}x\\y\end{bmatrix}$ は
\[\begin{bmatrix}1&0\\0&-1\\\end{bmatrix}
\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}x\\-y\end{bmatrix}\tag{2}\]
に変換されます。同様に、$y$ 軸に関する鏡映変換は
\[B=\begin{bmatrix}-1&0\\0&1\\\end{bmatrix}\tag{3}\]
で与えられます。鏡映変換を $2$ 回ほどこすと元に戻るので、鏡映変換行列 $Q$ について、常に $Q^2=I$ が成り立ちます。たとえば、(1) の $A$ を $2$ 乗してみると、
\[A^2=\begin{bmatrix}1&0\\0&-1\\\end{bmatrix}\begin{bmatrix}1&0\\0&-1\\\end{bmatrix}=\begin{bmatrix}1&0\\0&1\\\end{bmatrix}\]
となっています。同様に $B^2=I$ も成り立ちます。
Python を使って、行列 $A$ による $P(3,3)$ の点の移り先を確認しておきましょう。点を表示するために、当サイトの コードライブラリ に収められている coordinate() と pointer() を予め実装しておいてください。
# python_reflection
# In[1]
import numpy as np
import matplotlib.pyplot as plt
# ここにcoordinate()を実装
# ここにpointer()を実装
# FigureとAxes
fig = plt.figure(figsize = (5, 5))
ax = fig.add_subplot(111)
# FigureとAxes
fig = plt.figure(figsize = (6, 6))
ax = fig.add_subplot(111)
# 座標を準備
coordinate(ax, [-6, 6], [-6, 6])
# 鏡映行列aを定義
a = np.array([[1, 0],
[0, -1]])
# 変換前の点
p0 = np.array([3, 3])
# 変換後の点
p1 = np.dot(a, p0)
# 変換前の点p0をプロット
pointer(ax, p0[0], p0[1], "P0",
pcolor = "red", textsize = 15)
# 変換前の後の点p1をプロット
pointer(ax, p1[0], p1[1], "P1",
pcolor = "blue", textsize = 15)
plt.show()
線形変換は点の集合をまとめて変換することもできます。
たとえば、直線 $y=2x$ 上の点を $\begin{bmatrix}t\\2t\end{bmatrix}$ で表すと、行列 $A$ によって
\[\begin{bmatrix}1&0\\0&-1\\\end{bmatrix}\begin{bmatrix}t\\2t\end{bmatrix}=\begin{bmatrix}t\\-2t\end{bmatrix}\]
に変換されます。これは直線 $y=2x$ 上の点が直線 $y=-2x$ 上に写ることを意味します。これも Python で確認してみましょう。
numpy.linspace() で x のデータを作成し、x と 2*x を numpy.vstack で縦に連結すると、直線 $y=2x$ 上の各点を表す 2 次元ベクトルを横に並べた
\[\begin{bmatrix}-6.0&-5.8125&-5.625&-5.4375& ... \\-12.0&-11.625&-11.25&-10.825& ...\end{bmatrix}\]
という行列が生成されます。これに行列を作用させると、すべての点をまとめて変換できます。
# In[2]
# FigureとAxes
fig = plt.figure(figsize = (6, 6))
ax = fig.add_subplot(111)
# 座標を設定
coordinate(ax, [-6, 6], [-6, 6])
# 鏡映行列aを定義
a = np.array([[1, 0],
[0, -1]])
# x座標データ
x = np.linspace(-6, 6, 65)
# xと2xを縦に結合して直線データを作成
line_0 = np.vstack((x, 2*x))
# 行列aで直線を変換
line_1 = np.dot(a, line_0)
# 変換前の直線と変換後の直線をプロット
ax.plot(line_0[0], line_0[1],
color = "red", label = "y = 2x")
ax.plot(line_1[0], line_1[1],
color = "blue", label = "y = -2x")
# 凡例を表示
ax.legend()
plt.show()
直線に関する鏡映変換
任意の傾きをもつ直線 $y=mx$ について折り返しは
\[C=\frac{1}{1+m^2}\begin{bmatrix}1-m^2&2m\\2m&m^2-1\\\end{bmatrix}\tag{4}\]
によって表されます。この変換を実行する reflection()関数を定義して、点 $P_0(3, 3)$ の直線 $y=x/2$ に関する鏡映変換 (対称移動) を確認してみます。
# In[3]
def reflection(x, m):
a = np.array([[1 - m**2, 2*m],
[2*m, m**2 - 1]])
a = a / (1 + m**2)
ax = np.dot(a, x)
return ax
# FigureとAxes
fig = plt.figure(figsize = (6, 6))
ax = fig.add_subplot(111)
# 座標を準備
coordinate(ax, [-6, 6], [-6, 6])
# 鏡映行列aを定義
a = np.array([[1, 0],
[0, -1]])
# 変換前の点
p0 = np.array([3, 3])
# p0をy=0.5xに関して折り返す
p1 = reflection(p0, 0.5)
# y=0.5xをプロット
x = np.linspace(-6, 6, 65)
ax.plot(x, 0.5*x, color = "gray")
# 変換前の点p0をプロット
pointer(ax, p0[0], p0[1], "P0",
pcolor = "red", textsize = 15)
# 変換前の後の点p1をプロット
pointer(ax, p1[0], p1[1], "P1",
pcolor = "blue", textsize = 15)
鏡映変換をざっくり解説します
ChatGPT に鏡映変換について数式なしで説明してもらいました。
[ChatGPT] 鏡映変換は、オリジナルの対象を鏡のように反転させる変換です。直感的には、鏡映変換は、対象をある軸に沿って反転する操作と考えることができます。2次元空間における鏡映変換の例を考えてみましょう。まず、x軸に関して鏡映変換を行う場合を考えます。この場合、対象の上下が反転します。例えば、点 (2, 3) があった場合、鏡映変換により点 (2, -3) に移ります。同様に、点 (1, -4) は点 (1, 4) に移ります。もう一つの例として、y軸に関して鏡映変換を行う場合を考えましょう。この場合、対象の左右が反転します。例えば、点 (2, 3) があった場合、鏡映変換により点 (-2, 3) に移ります。同様に、点 (-1, -4) は点 (1, -4) に移ります。3次元空間でも同様の考え方が適用されます。鏡映変換は平面に関して行われます。平面が鏡線として機能し、対象がそれに沿って反転します。これにより、オリジナルの対象が鏡像として表されます。鏡映変換は直感的な操作であり、物体の形状を反転させたり対称性を持つ形状を作り出したりするために使用されます。例えば、鏡映変換は、鏡や水面の反射、光学のシミュレーション、グラフィックス、幾何学的な計算、物理学の問題など、さまざまな応用分野で利用されます。