【线性代数:从基向量理解线性变换与矩阵】附Python代码
2D线性变换
1. 线性变换的核心思想
线性变换是一种特殊的函数,输入一个向量,输出另一个向量,并且满足两个核心法则:
- 可加性:
f(u + v) = f(u) + f(v)
- 齐次性:
f(cu) = c * f(u)
矩阵则是这种变换在特定坐标系下的计算蓝图。
2. 基向量视角:理解变换的关键
标准坐标系的两个基向量:
- î = [1, 0]ᵀ (x轴单位向量)
- ĵ = [0, 1]ᵀ (y轴单位向量)
一个关键洞察:线性变换完全由它如何变换这两个基向量决定。
任何2D向量 [x, y]ᵀ 都可以表示为基向量的线性组合:v = x * î + y * ĵ
。应用线性变换 T 后:
T(v) = T(x * î + y * ĵ) = x * T(î) + y * T(ĵ)
变换后的基向量 T(î)
和 T(ĵ)
并排在一起,就构成了变换矩阵:
A = [ T(î) | T(ĵ) ]
计算方式:T(v) = A * v = [ T(î) | T(ĵ) ] * [x, y]ᵀ = x * T(î) + y * T(ĵ)
3. 常见2D线性变换及其矩阵
3.1 缩放 (Scaling)
import numpy as npdef scaling_matrix(sx, sy):"""创建缩放矩阵sx: x方向缩放因子sy: y方向缩放因子"""return np.array([[sx, 0],[0, sy]])# 示例:x方向放大2倍,y方向缩小0.5倍
S = scaling_matrix(2, 0.5)
print("缩放矩阵:\n", S)# 应用变换
v = np.array([3, 4]) # 原始向量
v_transformed = S.dot(v)
print("变换后向量:", v_transformed)
3.2 旋转 (Rotation)
import mathdef rotation_matrix(theta):"""创建旋转矩阵(逆时针旋转)theta: 旋转角度(弧度)"""cos_t = math.cos(theta)sin_t = math.sin(theta)return np.array([[cos_t, -sin_t],[sin_t, cos_t]])# 示例:旋转45度
theta = math.radians(45) # 转换为弧度
R = rotation_matrix(theta)
print("旋转矩阵:\n", R)# 应用变换
v = np.array([1, 0]) # 原始向量
v_transformed = R.dot(v)
print("变换后向量:", v_transformed)
3.3 剪切 (Shearing)
def shearing_matrix(kx, ky):"""创建剪切矩阵kx: x方向剪切因子ky: y方向剪切因子"""return np.array([[1, kx],[ky, 1]])# 示例:水平剪切
H = shearing_matrix(0.5, 0)
print("剪切矩阵:\n", H)# 应用变换
v = np.array([2, 3]) # 原始向量
v_transformed = H.dot(v)
print("变换后向量:", v_transformed)
3.4 反射 (Reflection)
def reflection_matrix(axis):"""创建反射矩阵axis: 反射轴 ('x', 'y', 或 'xy')"""if axis == 'x':return np.array([[1, 0],[0, -1]])elif axis == 'y':return np.array([[-1, 0],[0, 1]])elif axis == 'xy': # 关于直线y=x反射return np.array([[0, 1],[1, 0]])else:raise ValueError("不支持的反射轴")# 示例:关于x轴反射
F = reflection_matrix('x')
print("反射矩阵:\n", F)# 应用变换
v = np.array([2, 3]) # 原始向量
v_transformed = F.dot(v)
print("变换后向量:", v_transformed)
4. 组合变换
线性变换的强大之处在于可以组合,通过矩阵乘法实现:
# 组合变换:先旋转45度,再x方向放大2倍
theta = math.radians(45)
R = rotation_matrix(theta)
S = scaling_matrix(2, 1)# 注意顺序:先应用的变换放在右边
M = S.dot(R) # 先旋转,后缩放
print("组合变换矩阵:\n", M)# 应用组合变换
v = np.array([1, 1]) # 原始向量
v_transformed = M.dot(v)
print("变换后向量:", v_transformed)
5. 平移与齐次坐标
平移不是线性变换,但可以通过齐次坐标实现:
def translation_matrix(tx, ty):"""创建平移矩阵(使用齐次坐标)tx: x方向平移量ty: y方向平移量"""return np.array([[1, 0, tx],[0, 1, ty],[0, 0, 1]])def to_homogeneous(v):"""转换为齐次坐标"""return np.array([v[0], v[1], 1])def from_homogeneous(v_h):"""从齐次坐标转换回普通坐标"""return np.array([v_h[0]/v_h[2], v_h[1]/v_h[2]])# 示例:平移变换
T = translation_matrix(3, 2)
print("平移矩阵:\n", T)# 应用变换(需要先将向量转换为齐次坐标)
v = np.array([1, 1])
v_h = to_homogeneous(v)
v_transformed_h = T.dot(v_h)
v_transformed = from_homogeneous(v_transformed_h)
print("变换后向量:", v_transformed)
6. 几何意义:行列式
变换矩阵的行列式有重要的几何意义:
# 计算各种变换的行列式
S = scaling_matrix(2, 3) # 缩放矩阵
R = rotation_matrix(math.radians(30)) # 旋转矩阵
H = shearing_matrix(0.5, 0) # 剪切矩阵print("缩放矩阵行列式:", np.linalg.det(S)) # 面积缩放比例
print("旋转矩阵行列式:", np.linalg.det(R)) # 应为1(保面积)
print("剪切矩阵行列式:", np.linalg.det(H)) # 应为1(保面积)
7. 可视化变换效果
import matplotlib.pyplot as pltdef plot_transformation(original, transformed, title):"""绘制变换前后的向量"""plt.figure(figsize=(10, 5))plt.subplot(1, 2, 1)plt.quiver(0, 0, original[0], original[1], angles='xy', scale_units='xy', scale=1, color='r')plt.xlim(-5, 5)plt.ylim(-5, 5)plt.grid(True)plt.title('原始向量')plt.axhline(y=0, color='k')plt.axvline(x=0, color='k')plt.subplot(1, 2, 2)plt.quiver(0, 0, transformed[0], transformed[1], angles='xy', scale_units='xy', scale=1, color='b')plt.xlim(-5, 5)plt.ylim(-5, 5)plt.grid(True)plt.title(title)plt.axhline(y=0, color='k')plt.axvline(x=0, color='k')plt.tight_layout()plt.show()# 示例:可视化旋转变换
v = np.array([3, 2])
theta = math.radians(60)
R = rotation_matrix(theta)
v_transformed = R.dot(v)plot_transformation(v, v_transformed, '旋转变换后')