1. 翻訳
2D 空間では、ある点を別の点に変換する必要があることがよくあります。空間内の点P ( x , y ) P(x,y) を仮定します。P ( x ,y ) ; それをx 、 yx 、 y× 、tx t_x をy方向に移動しますt×、ty t_ytはい、変換後の点の座標が( x ' , y ' ) (x',y')であると仮定します。( ×「、」y' )の場合、上記の点の変換操作は次の式のように要約できます:
x ' = x + txy ' = x + ty \begin{alignat}{2} &x'=x + t_x\\ &y'=x + t_y \end {整列}バツ』=バツ+t×y』=バツ+tはい
同次行列の使用は次のように表されます:
[ x ' y ' 1 ] = [ 1 btx 0 1 ty 0 0 1 ] [ xy 1 ] \begin{bmatrix} x' \\ y' \\ 1 \ end{bmatrix} = \ begin{bmatrix} 1 & b & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix }
バツ』y』1
=
100b10t×tはい1
バツy1
import numpy as np
def translation():
"""
原始数组a 三个点(1,1) (4,4) (7,7)
构建齐次矩阵 P
构建变换矩阵 T
"""
a = np.array([[1, 1],
[4, 4],
[7, 7]])
P = np.array([a[:, 0],
a[:, 1],
np.ones(len(a))])
T = np.array([[1, 0, 2],
[0, 1, 2],
[0, 0, 1]])
return np.dot(T, P)
print(translation())
"""
[[3. 6. 9.]
[3. 6. 9.]
[1. 1. 1.]]
"""
アニメーション効果のデモンストレーション
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
X, Y = np.mgrid[0:1:5j, 0:1:5j]
x, y = X.ravel(), Y.ravel()
def trans_translate(x, y, tx, ty):
T = [[1, 0, tx],
[0, 1, ty],
[0, 0, 1]]
T = np.array(T)
P = np.array([x, y, [1] * x.size])
return np.dot(T, P)
fig, ax = plt.subplots(1, 4)
T_ = [[0, 0], [2.3, 0], [0, 1.7], [2, 2]]
for i in range(4):
tx, ty = T_[i]
x_, y_, _ = trans_translate(x, y, tx, ty)
ax[i].scatter(x_, y_)
ax[i].set_title(r'$t_x={0:.2f}$ , $t_y={1:.2f}$'.format(tx, ty))
ax[i].set_xlim([-0.5, 4])
ax[i].set_ylim([-0.5, 4])
ax[i].grid(alpha=0.5)
ax[i].axhline(y=0, color='k')
ax[i].axvline(x=0, color='k')
plt.show()
2. スケーリング
2D 空間では、点( x , y ) (x,y)( x ,y )別の点( px , py ) (p_x,p_y)( p×、pはい)スケーリング操作の場合、 x、yx、yの係数をスケーリングすることもできます。x 方向とy方向はそれぞれsx 、 sy s_x、 s_ys×、sはいとすると、上記のスケーリング操作は次の式のように要約できます。
x ' = sx ( x − px ) + px = sxx + px ( 1 − sx ) y ' = sy ( y − py ) + py = syy + py ( 1 − sy ) \begin{alignat}{2} &x'=s_x(x-p_x) + p_x &=s_xx + p_x(1-s_x)\\ &y'=s_y(y-p_y) + p_y &=s_yy + p_y( 1-s_y) \end{alignat}バツ』=s×( ×−p×)+p×y』=sはい( y−pはい)+pはい=s×バツ+p×( 1−s×)=sはいy+pはい( 1−sはい)
同次行列の使用は次のように表されます:
[ x ' y ' 1 ] = [ sx 0 px ( 1 − sx ) 0 sypy ( 1 − sy ) 0 0 1 ] [ xy 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} s_x& 0 & p_x(1-s_x) \\ 0 & s_y& p_y(1-s_y)\\ 0 & 0& 1 \end{bmatrix } \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}
バツ』y』1
=
s×000sはい0p×( 1−s×)pはい( 1−sはい)1
バツy1
def trans_scale(x, y, px, py, sx, sy):
T = [[sx, 0 , px*(1 - sx)],
[0 , sy, py*(1 - sy)],
[0 , 0 , 1 ]]
T = np.array(T)
P = np.array([x, y, [1]*x.size])
return np.dot(T, P)
fig, ax = plt.subplots(1, 4)
S_ = [[1, 1], [1.8, 1], [1, 1.7], [2, 2]]
P_ = [[0, 0], [0, 0], [0.45, 0.45], [1.1, 1.1]]
for i in range(4):
sx, sy = S_[i]; px, py = P_[i]
x_, y_, _ = trans_scale(x, y, px, py, sx, sy)
ax[i].scatter(x_, y_)
ax[i].scatter(px, py)
ax[i].set_title(r'$p_x={0:.2f}$ , $p_y={1:.2f}$'.format(px, py) + '\n'
r'$s_x={0:.2f}$ , $s_y={1:.2f}$'.format(sx, sy))
ax[i].set_xlim([-2, 2])
ax[i].set_ylim([-2, 2])
ax[i].grid(alpha=0.5)
ax[i].axhline(y=0, color='k')
ax[i].axvline(x=0, color='k')
plt.show()
3. 回転
2D 空間では、点( x , y ) (x,y)に対して( x ,y )別の点( px , py ) (p_x,p_y)( p×、pはい)回転操作の場合、回転角度をβ \betaと仮定すると、一般に反時計回りが正、時計回りが負です。β、次に上記の点x 、yx、y× 、点px、py p_x、p_yを基準としたyp×、pはい回転角β \betaβ関数を関数として定義します。
[ x ′ y ′ 1 ] = [ cos β − sin β px ( 1 − cos β ) + py sin β sin β cos β py ( 1 − cos β ) + px sin β 0 0 1 ] [ xy 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} \cos \beta& -\sin \beta & p_x(1-\cos \beta) + p_y \sin \beta \\ \sin \beta & \cos \beta& p_y(1-\cos \beta) + p_x \sin \beta \\ 0 & 0& 1 \end {bmatrix} \begin{bmatrix}x\\y\\1\end{bmatrix}
バツ』y』1
=
コスb罪b0−罪bコスb0p×( 1−コスb )+pはい罪bpはい( 1−コスb )+p×罪b1
バツy1
def trans_rotate(x, y, px, py, beta):
beta = np.deg2rad(beta)
T = [[np.cos(beta), -np.sin(beta), px*(1 - np.cos(beta)) + py*np.sin(beta)],
[np.sin(beta), np.cos(beta), py*(1 - np.cos(beta)) - px*np.sin(beta)],
[0 , 0 , 1 ]]
T = np.array(T)
P = np.array([x, y, [1]*x.size])
return np.dot(T, P)
fig, ax = plt.subplots(1, 4)
R_ = [0, 225, 40, -10]
P_ = [[0, 0], [0, 0], [0.5, -0.5], [1.1, 1.1]]
for i in range(4):
beta = R_[i]; px, py = P_[i]
x_, y_, _ = trans_rotate(x, y, px, py, beta)
ax[i].scatter(x_, y_)
ax[i].scatter(px, py)
ax[i].set_title(r'$\beta={0}°$ , $p_x={1:.2f}$ , $p_y={2:.2f}$'.format(beta, px, py))
ax[i].set_xlim([-2, 2])
ax[i].set_ylim([-2, 2])
ax[i].grid(alpha=0.5)
ax[i].axhline(y=0, color='k')
ax[i].axvline(x=0, color='k')
plt.show()
4. シャーリング
2D 空間では、点( x , y ) (x,y)に対して( x ,y )別の点( px , py ) (p_x,p_y)( p×、pはい)弾性体の変形処理に一般的に使用されるミスカット操作用。x 方向と y 方向に沿ったミスカット パラメーターがλ x 、 λ y \lambda _x, \lambda _y私×、lはいの場合、ミスカット操作は次のように要約され、同次行列として表現できます。
[ x ′ y ′ 1 ] = [ 1 λ x − λ xpx λ y 1 − λ ypy 0 0 1 ] [ xy 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \ begin{bmatrix} 1& \lambda _x & -\lambda _x p_x \\ \lambda _y & 1& -\lambda _y p_y \\ 0 & 0& 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \ 終了{b行列} バツ』y』1 = 1私はい0私×10− l×p×− lはいpはい1 バツy1
import matplotlib.pyplot as plt
import numpy as np
X, Y = np.mgrid[0:1:5j, 0:1:5j]
x, y = X.ravel(), Y.ravel()
def trans_shear(x, y, px, py, lambdax, lambday):
T = [[1 , lambdax, -lambdax*px],
[lambday, 1 , -lambday*py],
[0 , 0 , 1 ]]
T = np.array(T)
P = np.array([x, y, [1]*x.size])
return np.dot(T, P)
fig, ax = plt.subplots(1, 4)
L_ = [[0, 0], [2, 0], [0, -2], [-2, -2]]
P_ = [[0, 0], [0, 0], [0, 1.5], [1.1, 1.1]]
for i in range(4):
lambdax, lambday = L_[i]; px, py = P_[i]
x_, y_, _ = trans_shear(x, y, px, py, lambdax, lambday)
ax[i].scatter(x_, y_)
ax[i].scatter(px, py)
ax[i].set_title(r'$p_x={0:.2f}$ , $p_y={1:.2f}$'.format(px, py) + '\n'
r'$\lambda_x={0:.2f}$ , $\lambda_y={1:.2f}$'.format(lambdax, lambday))
ax[i].set_xlim([-3, 3])
ax[i].set_ylim([-3, 3])
ax[i].grid(alpha=0.5)
ax[i].axhline(y=0, color='k')
ax[i].axvline(x=0, color='k')
plt.show()
5. 反省
ミラーリングの場合、対称軸の法線ベクトル v ( vx , vy ) v(v_x,v_y)v ( v×、vはい)、ミラー行列T m T_{m}Tメートル表示:
[ 1 − 2 xv 2 − 2 xvyv 0 − 2 xvyv 1 − 2 yv 2 0 0 0 1 ] \left[ \begin{array}{ccc} 1-2 x_{v}{ }^{2} & -2 x_{v} y_{v} & 0 \\ -2 x_{v} y_{v} & 1-2 y_{v}{ }^{2} & 0 \\ 0 & 0 & 1 \end {配列} \右]
1−2倍_v2−2x _ _vyv0−2x _ _vyv1−2年v20001
さらに、対称軸の位置 (対称軸の 2 点の任意の点) を表すために点が必要で、M ( xm , ym ) M\left(x_{\mathrm{m}}, y_として表されます) {m}\右)M( ×メートル、yメートル)、変換行列H = T t ∗ T m ∗ T t − 1 H = T_{t}*T_{m}*T_{t}^{-1}H=Tた∗Tメートル∗Tt− 1:
H = [ 1 0 0 0 1 0 xmym 1 ] [ 1 − 2 xv 2 − 2 xvyv 0 − 2 xvyv 1 − 2 yv 2 0 0 0 1 ] [ 1 0 0 0 1 0 − xm − ym ] H = \left[\begin{array}{ccc}1&0&0\\0&1&0\\x_{\mathrm{m}}&y_{m}&1\end{array}\right ] \left[\begin{array}{ccc}1 -2x_{v}{}^{2}&-2x_{v}y_{v}&0\\-2x_{v}y_{v} &1-2 y_{v}{}^{2}&0\\0&0&1 \end{array}\right]\left[\begin{array}{ccc}1&0&0\\0 &1&0\\-x_{\mathrm{m}}&-y_{m}&1\end{array}\right]H=
10バツメートル01yメートル001
1−2倍_v2−2x _ _vyv0−2x _ _vyv1−2年v20001
10− ×メートル01− yメートル001
ミラーリング後の座標はTo ∗ T t ∗ T m ∗ T t − 1 T_{o}*T_{t}*T_{m}*T_{t}^{-1} となります。Tああ∗Tた∗Tメートル∗Tt− 1。
X軸に沿ってミラーリングするためのミラー行列
: [ 1 0 0 0 − 1 0 1 0 1 ] \left[ \begin{array}{ccc} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 1 & 0 & 1 \end{配列} \right]
1010− 10001
Y軸に沿ってミラーリングするためのミラー行列
: [ − 1 0 0 0 1 0 0 1 1 ] \left[ \begin{array}{ccc} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 1 & 1 \end{配列} \right]
− 100011001
import numpy as np
a = np.array([[1, 2],
[2, 2],
[3, 5],
[4, 6]])
a = np.array([a[:,0], a[:,1], np.ones(len(a))])
print("\n",a)
print("--------------------------------")
T_x = np.array( [[ 1, 0, 0],
[ 0, -1, 0],
[ 1, 0, 1]])
print("\n",np.dot(T_x, a))
print("=================================")
T_y = np.array( [[-1, 0, 0],
[ 0, 1, 0],
[ 0, 1, 1]])
print("\n",np.dot(T_y, a))
参考:
https://zhuanlan.zhihu.com/p/387578291
https://zhuanlan.zhihu.com/p/187411029
https://blog.csdn.net/Akiyama_sou/article/details/122144415