matplotlib.pyplot
ライブラリのplot
関数は、複数の点を結んで折れ線グラフを描画するものです。これまでの授業では、数列や関数のグラフを描画するために使用してきました。
今回の授業では、plot
関数を使用することで線分を組み合わせてできるような図形を描画します。
三つの点 $(0,0),(1,0),(1,1)$ を頂点にもつような三角形を描画してみましょう。
このような三角形を描画するには、当然ながら $(0,0)$ と $(1,0)$、$(1,0)$ と $(1,1)$、$(1,1)$ と $(0,0)$ をそれぞれ線分で結ぶ必要があります。そのため、次のようなNumPyの $2\times 4$ の2次元配列(行列)triangle_nodes
を用意します。
import numpy as np
triangle_nodes = np.array([[0,0],[1,0],[1,1],[0,0]]).T #「.T」は行列の転置
#triangle_nodes = np.array([[0,1,1,0],[0,0,1,0]])でもよいが、上のように点ごとに入力してから転置すると簡単
#閉じた図形の場合、最初の点を最後にも入れる必要があることに注意
print(triangle_nodes)
[[0 1 1 0] [0 0 1 0]]
このとき、この行列の第0行triangle_nodes[0,:]
が $x$ 座標のリスト、第1行triangle_nodes[1,:]
が $y$ 座標のリストに対応するため、三角形の描画のコードは次のようになります。
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") #アスペクト比(縦横比)を1:1にする
plt.plot(triangle_nodes[0,:],triangle_nodes[1,:],"r-") #三角形の描画
plt.show()
続いて、三角形と四角形を組み合わせて家の図を描画してみましょう。
考える三角形の頂点を $(0,3),(-3,2),(3,2)$、四角形の頂点を $(-2,2),(-2,0),(2,0),(2,2)$ とし、それぞれの情報を変数roof_nodes
とwall_nodes
に格納することにします。
import numpy as np
import matplotlib.pyplot as plt
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,:],"r-") #屋根の描画
plt.plot(wall_nodes[0,:],wall_nodes[1,:],"r-") #壁の描画
plt.show()
自分なりの家の図を描画してください。屋根や壁の形を変えるほか、適当に窓やドアなどを追加すると良いです。
#演習1のコード
import numpy as np
import matplotlib.pyplot as plt
#ここに、コードを書く
#roof_nodes、wall_nodesに加え、必要に応じてwindow_nodes、door_nodesなどを用意する
与えられた点や図形に対して、幾何変換(幾何学的な変換)を行うことを考えます。
変換前の点を $(x,y)$、変換後の点を $(x',y')$ とするとき、$2\times 2$ 行列 $A$ を用いて
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} =A \begin{pmatrix} x\\ y \end{pmatrix} $$と表されるのが線形変換(linear transformation)です。
重要なこととして、上で考えたような図形を特徴付ける複数の点からなる行列($2\times n$ 行列)に対して $A$ を左から掛ければ、全ての点に対する線形変換、すなわち図形に対する線形変換を行うことができます。
線形変換は様々に考えられますが、以下では重要なものを紹介します。
拡大・縮小変換は、原点を中心に一定の倍率での拡大・縮小を行う線形変換です。
$x$ 軸方向に $\alpha$ 倍、$y$ 軸方向に $\beta$ 倍する変換は、
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} \alpha & 0\\ 0 & \beta \end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix} $$と表されます。
例として、1.1の三角形に対して $x$ 軸方向に $2$ 倍、$y$ 軸方向に $1.5$ 倍する変換を行うと、次のようになります。
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]]) #変換行列
new_triangle_nodes = A@triangle_nodes #変換後の点からなる行列
plt.plot(new_triangle_nodes[0,:],new_triangle_nodes[1,:],"b-") #変換後の三角形の描画(青色)
plt.show()
回転変換は、原点を中心に一定の角度での回転を行う線形変換です。
反時計回りに角度 $\theta$(単位はラジアン)だけ回転する変換は、
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta \end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix} $$と表されます。
例として、1.1の三角形に対して反時計回りに $10$ 度だけ回転する変換を行うと、次のようになります。
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-") #変換前の三角形の描画(赤色)
theta = 10/180*np.pi #度をラジアンに直す
A = np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]]) #変換行列
new_triangle_nodes = A@triangle_nodes #変換後の点からなる行列
plt.plot(new_triangle_nodes[0,:],new_triangle_nodes[1,:],"b-") #変換後の三角形の描画(青色)
plt.show()
対称変換は、原点を通るある直線に関して対称移動を行う線形変換です。
特に、$x$ 軸に関して対称移動する変換は
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} 1 & 0\\ 0 & -1 \end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix}, $$$y$ 軸に関して対称移動する変換は
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} -1 & 0\\ 0 & 1 \end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix}, $$直線 $y=x$ に関して対称移動する変換は
$$ \begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} 0 & 1\\ 1 & 0 \end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix} $$と表されます。
例として、1.1の三角形に対して $y$ 軸に関して対称移動する変換を行うと、次のようになります。
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([[-1,0],[0,1]]) #変換行列
new_triangle_nodes = A@triangle_nodes #変換後の点からなる行列
plt.plot(new_triangle_nodes[0,:],new_triangle_nodes[1,:],"b-") #変換後の三角形の描画(青色)
plt.show()
1.2の家(または演習1で考えた自分なりの家)に対して何かしらの拡大・縮小変換、回転変換、対称変換を一つずつ行い、変換前の家と合わせて四つの家を一つの図に描画してください。ただし、別々の色にすること。
#演習2のコード
import numpy as np
import matplotlib.pyplot as plt
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,:],"r-")
plt.plot(wall_nodes[0,:],wall_nodes[1,:],"r-")
#ここに、コードを書く
#A、new_roof_nodes、new_wall_nodesを作成する
plt.show()
線形変換の一種であるせん断変換についてWikipediaなどで調べた上で、1.2の家(または演習1で考えた自分なりの家)に対して何かしらのせん断変換を行い、変換前の家と変換後の家を一つの図に描画してください。ただし、別々の色にすること。
#演習3のコード
演習1~演習3に取り組んでください。