二维平面上常见的三种几何变换
- 平移
- 缩放
- 旋转
平移
在二维平面上每个点可以用
表示,假设有一点
,它平移到
,则相应的数学表达式子为:
例如,点 平移到 需要相应的
缩放
假设有一点
,它缩放到
,则相应的数学表达式子为:
其中, 代表缩放的矩阵。
旋转
二维平面是上的旋转矩阵如下,
想要知道详细这个矩阵的详细推导可以看这篇博客;
那么,假设有一点 ,它绕着原点旋转到 ,则相应的数学表达式子为:
齐次坐标系的引入
在二维平面上,缩放和旋转通过乘法实现,平移是通过加法实现,这样计算是很麻烦地!为了规范二维平面上的几何变换,数学家们引入了齐次坐标的概念。
齐次坐标的是什么呢?直观上来讲就是在原来的维度上面再添加一个维度,且多出的维度一直是1,例如:
则上述平移过程中的
在齐次坐标系的表达方式为:
利用齐次坐标系,平移过程的数学表达式为:
上述缩放过程中,
在齐次坐标系中的表达方式为:
扫描二维码关注公众号,回复:
1056947 查看本文章
则缩放过程的数学表达式为:
同理,上述旋转过程中的旋转矩阵
在其次坐标系统的表达方式为:
则旋转过程的数学表达式为:
至此,二维平面上所有几何变换都可以通过乘法实现。比如,在二维平面上要实现绕着某个点 旋转,需要以下三个步骤完成:
- 将图形平移到原点
- 对图形进行旋转
- 将图形平移回原来的位置
没有利用齐次坐标系的话,变换过程的数学公式为:
利用齐次坐标系的话,变换过程的数学公式为:
下面用根据本篇文章的知识,利用Python实现一个正方形绕着中心点旋转45度的例子。
import numpy as np
import matplotlib.pyplot as plt
def poly_gen(x0=(10,10),length = 20):
poly = []
x = x0[0]
y = x0[1]
for _ in range(length):
y += 1
poly.append(np.array([x,y,1]))
x = x0[0]
y = x0[1]
for _ in range(length):
x += 1
poly.append(np.array([x,y,1]))
x = x0[0]+length
y = x0[1]
for _ in range(length):
y += 1
poly.append(np.array([x,y,1]))
x = x0[0]
y = x0[1]+length
for _ in range(length):
x +=1
poly.append(np.array([x,y,1]))
center = np.array([x0[0]+length/2,x0[1]+length/2])
return poly, center
def translation(poly,dx,dy):
T = np.array([[1,0,dx],
[0,1,dy],
[0,0,1]])
poly_trans = []
for x in poly:
poly_trans.append(np.dot(T,x))
return poly_trans
def rotation(poly,theta):
R = np.array([[np.cos(theta), np.sin(theta),0],
[-np.sin(theta),np.cos(theta),0],
[0,0,1]])
poly_rotation = []
for x in poly:
poly_rotation.append(np.dot(R,x))
return poly_rotation
if __name__=='__main__':
fig1=plt.figure()
poly, center = poly_gen()
for x in poly:
plt.scatter(x[0],x[1])
plt.xlim(0,50)
plt.ylim(0,50)
fig2=plt.figure()
poly_trans = translation(poly,-center[0],-center[1])
poly_rotation = rotation(poly_trans, np.pi / 4.)
poly_trans = translation(poly_rotation,center[0],center[1])
for x in poly_trans:
plt.scatter(x[0],x[1])
plt.xlim(0,50)
plt.ylim(0,50)
plt.show()
其运行的结果如下: