前回の授業では、与えられた点や図形に対して幾何変換を行うことを考え、行列を用いて表現される線形変換(特に、拡大・縮小変換、回転変換、対称変換、せん断変換)について扱いました。
今回の授業では、平行移動とアフィン変換について扱います。
変換前の点を $(x,y)$、変換後の点を $(x',y')$ とするとき、$x$ 軸方向に $p$、$y$ 軸方向に $q$ だけ平行移動する変換は、
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} x\\ y \end{pmatrix} + \begin{pmatrix} p\\ q \end{pmatrix} $$と表されます。
例として、前回の1.1の三角形に対して $x$ 軸方向に $2$、$y$ 軸方向に $1$ だけ平行移動する変換を行うと、次のようになります。
import numpy as np
import matplotlib.pyplot as plt
triangle_nodes = np.array([[0,0],[1,0],[1,1],[0,0]]).T #変換前の点からなる行列
plt.gca().set_aspect("equal")
plt.plot(triangle_nodes[0,:],triangle_nodes[1,:],"r-") #変換前の三角形の描画(赤色)
b = np.array([[2,1]]).T #平行移動ベクトル
new_triangle_nodes = triangle_nodes+b #変換後の点からなる行列(各列にbを足す)
plt.plot(new_triangle_nodes[0,:],new_triangle_nodes[1,:],"b-") #変換後の三角形の描画(青色)
plt.show()
アフィン変換(affine transformation)は、線形変換と平行移動を組み合わせた変換であり、
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} =A \begin{pmatrix} x\\ y \end{pmatrix} + \begin{pmatrix} p\\ q \end{pmatrix} $$の形で表されます。ここで、$A$ は $2\times 2$ の行列です。
$p=q=0$ の場合には線形変換、$A$ が単位行列の場合には平行移動になるため、アフィン変換は線形変換および平行移動を一般化した概念であることが分かります。
例として、前回の1.1の三角形に対して $x$ 軸方向に $2$ 倍、$y$ 軸方向に $1.5$ 倍してから $x$ 軸方向に $2$、$y$ 軸方向に $1$ だけ平行移動する変換を行うと、次のようになります。
import numpy as np
import matplotlib.pyplot as plt
triangle_nodes = np.array([[0,0],[1,0],[1,1],[0,0]]).T #変換前の点からなる行列
plt.gca().set_aspect("equal")
plt.plot(triangle_nodes[0,:],triangle_nodes[1,:],"r-") #変換前の三角形の描画(赤色)
A = np.array([[2,0],[0,1.5]]) #線形変換行列
b = np.array([[2,1]]).T #平行移動ベクトル
new_triangle_nodes = A@triangle_nodes+b #変換後の点からなる行列
plt.plot(new_triangle_nodes[0,:],new_triangle_nodes[1,:],"b-") #変換後の三角形の描画(青色)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
def house():
roof_nodes = np.array([[0,3],[-3,2],[3,2],[0,3]]).T
wall_nodes = np.array([[-2,2],[-2,0],[2,0],[2,2],[-2,2]]).T
plt.gca().set_aspect("equal")
plt.plot(roof_nodes[0,:],roof_nodes[1,:],color="purple")
plt.fill(roof_nodes[0,:],roof_nodes[1,:],color="purple",alpha=0.5) #不透明度0.5で塗りつぶす
plt.plot(wall_nodes[0,:],wall_nodes[1,:],color="purple")
house() #定義した関数を呼び出す
plt.show() #後で複数の家を一つの図に描画するため、関数の中には入れない
matplotlib
における色の指定方法は、色の頭文字、カラーネーム、RGB形式、16進数カラーコードなど複数用意されています。詳しくは、参考リンクをご覧ください。
自分なりの家の図を描画する関数house()
を定義し、その関数を呼び出してください。前回の演習1の内容に加えて、適宜塗りつぶしや色の変更を行うこと。
#演習1のコード
import numpy as np
import matplotlib.pyplot as plt
def house():
#ここに、コードを書く
#plt.show()は不要
house()
plt.show()
次に、家に対して任意のアフィン変換を行った結果を描画する関数を定義します。
演習1の家に対して行列 $A$ と ベクトル $b$ によるアフィン変換を行った結果を描画する関数house_transform(A,b)
を定義し、変換前の家と適当なアフィン変換を行った家を一つの図に描画してください。
#演習2のコード
import numpy as np
import matplotlib.pyplot as plt
def house_transform(A,b):
#ここに、コードを書く
#plt.show()は不要
house() #変換前の家の描画
#ここで、Aとbを適当に定める
house_transform(A,b) #変換後の家の描画
plt.show()
演習1の関数house()
と演習2の関数house_transform(A,b)
を利用して、
変換前の家
反時計回りに $15$ 度だけ回転した後、$x$ 軸方向に $2$、$y$ 軸方向に $3$ だけ平行移動した家
$x$ 軸方向に $2$、$y$ 軸方向に $3$ だけ平行移動した後、反時計回りに $15$ 度だけ回転した家
を一つの図に描画してください。
さらに、線形変換と平行移動の順番を変えることの意味について考察してください。
#演習3のコード
(Markdownとして考察を書く)
演習1~演習3に取り組んでください。