これは既出「図形変形のためのアフィン変換」のGoogle Colaboratory 版です。ただし、パラメータの入れ直しや変換順の変更はできませんでした。お許しください。
Google で Python を実行する方法は、「Google で Python その1」の「まえがき」をご参照ください。
なお、本Google Colab版「図形変換のためのアフィン変換」はGoogle Colab専用です。通常のPython 開発環境では「Ipython がない」というエラーが出ます。
# 2次元図形「box」のアフィン変換。2023.01.11 by Kero
# modified for Google Colaboratory 2023.01.29 by Kero
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML
# アフィン変換の宣言。
print('2次元座標サンプル(台形)のアフィン変換を行列演算で実行します。')
print('座標行列 x に 変換処理(T) を Tx の形で行います。')
print('変換は、A:回転、B:拡大、C:せん断、D:鏡映、E:平行移動、です。')
print('各変換のパラメータ入力は、空リターンで標準値が入ります。')
print('変換順は、英記号で入力してください。空リターンでおわりです。')
print('表示に1分近くかかることがあります。ご了承ください。')
print('')
# プロットエリアの設定。xy軸は同じ長さ。
def gurafu():
plt.xlim(-10.,10.)
plt.ylim(-10.,10.)
plt.xticks(np.arange(-10, 11, 2))
plt.yticks(np.arange(-10, 11, 2))
ax.set_aspect('equal', adjustable='box')
plt.grid(which='major')
# 座標群を行列にします。一筆書きになります。szはすべて1。
def tensen(t):
sx = np.array([])
sy = np.array([])
sz = np.array([])
for i in range(t.shape[0]): # shape は配列の長さ。
sx = np.append(sx, t[i,0])
sy = np.append(sy, t[i,1])
sz = np.append(sz, 1)
return np.concatenate([[sx],[sy],[sz]])
# 入力値が数値かチェック。
def isnum(t: str) -> bool:
try:
float(t)
return True
except ValueError:
return False
# 回転のマトリックス設定。
def A(drd,i):
rd = drd * i
Am = np.array([[np.cos(rd), -np.sin(rd), 0],
[np.sin(rd), np.cos(rd), 0],
[0., 0., 1.]])
return Am
# 拡大のマトリックス設定。
def B(dkax, dkay,i):
Bm = np.array([[dkax * i + 1., 0, 0],
[0, dkay * i + 1., 0],
[0, 0, 1]])
return Bm
# せん断のマトリックス設定。
def C(dsex, dsey, i):
sex = dsex * i
sey = dsey * i
Cm = np.array([[1., np.tan(sex), 0.],
[np.tan(sey), 1., 0.],
[0., 0., 1.]])
return Cm
# 鏡映のマトリックス設定
def D(dkyx, dkyy, i, kyx, kyy):
if kyx == '1':
a22 = dkyx * i * 2 + 1.
else:
a22 = 1.
if kyy == '1':
a11 = dkyy * i * 2 + 1.
else:
a11 = 1.
Dm = np.array([[a11, 0., 0.],
[0., a22, 0.],
[0., 0., 1.]])
return Dm
# 平行移動のマトリックス設定。
def E(didx, didy, i):
idx = didx * i
idy = didy * i
Em = np.array([[1., 0., idx],
[0., 1., idy],
[0., 0., 1.]])
return Em
# サンプルとしての形状座標群(台形)。
box = np.array([[0., 0.],
[3., 0.],
[3., 2.],
[0., 3.],
[0., 0.]])
# パラメータ入力。
print('【パラメータ入力】')
# 1.回転
do = input('A:回転:回転角度?(度):')
if (do == '') or (not(isnum(do))):
drd = 0
else:
drd = 0.01 * np.radians(float(do))
# 2.拡大
kax = input('B:拡大:xの拡大率? :')
if (kax == '') or (not(isnum(kax))):
dkax = 0.
else:
dkax = 0.01 * (float(kax) - 1.)
kay = input('B:拡大:yの拡大率? :')
if (kay == '') or (not(isnum(kay))):
dkay = 0.
else:
dkay = 0.01 * (float(kay) - 1.)
# 3.せん断
sex = input('C:せん断:y軸をx軸方向へ何度?:')
if (sex == '') or (not(isnum(sex))):
dsex = 0.
else:
dsex = 0.01 * np.radians(float(sex))
sey = input('C:せん断:x軸をy軸方向へ何度?:')
if (sey == '') or (not(isnum(sey))):
dsey = 0.
else:
dsey = 0.01 * np.radians(float(sey))
# 4.鏡映
kyx = input('D:鏡映:x軸対称(0/1)?:')
kyy = input('D:鏡映:y軸対称(0/1)?:')
if kyx == '1':
dkyx = -0.01
else:
dkyx = 0.01
kyx = '0'
if kyy == '1':
dkyy = -0.01
else:
dkyy = 0.01
kyy = '0'
# 5.平行移動
idx = input('E:平行移動:x方向?:')
if (idx == '') or (not(isnum(idx))):
didx = 0.
else:
didx = 0.01 * float(idx)
idy = input('E:平行移動:y方向?:')
if (idy == '') or (not(isnum(idy))):
didy = 0.
else:
didy = 0.01 * float(idy)
# 変換順の入力
print('')
print('【変換順(英記号)入力】')
jun = []
while True:
hen = input('変換は?:')
if hen == '':
break
jun.append(hen.upper())
# アニメ化。
fig, ax = plt.subplots()
artists = []
gurafu()
# 原型はブルーで表示。
boxline = tensen(box) # 座標行列を作成。
plt.plot(boxline[0], boxline[1], c='b')
# 入力順に変換の実行。
for j in jun:
print(j)
if j == 'A':
for d in range(101):
Am = A(drd,d)
boxline2 = np.dot(Am, boxline)
artist = ax.plot(boxline2[0], boxline2[1], c='r')
artists.append(artist)
elif j == 'B':
for d in range(101):
Bm = B(dkax,dkay,d)
boxline2 = np.dot(Bm, boxline)
artist = ax.plot(boxline2[0], boxline2[1], c='r')
artists.append(artist)
elif j == 'C':
for d in range(101):
Cm = C(dsex,dsey,d)
boxline2 = np.dot(Cm, boxline)
artist = ax.plot(boxline2[0], boxline2[1], c='r')
artists.append(artist)
elif j == 'D':
for d in range(101):
Dm = D(dkyx,dkyy,d, kyx, kyy)
boxline2 = np.dot(Dm, boxline)
artist = ax.plot(boxline2[0], boxline2[1], c='r')
artists.append(artist)
elif j == 'E':
for d in range(101):
Em = E(didx,didy,d)
boxline2 = np.dot(Em, boxline)
artist = ax.plot(boxline2[0], boxline2[1], c='r')
artists.append(artist)
boxline = boxline2
anim = animation.ArtistAnimation(fig, artists, interval=50)
rc('animation', html='jshtml')
plt.close()
anim
まあ、良いとするか。