
1. 引言在计算机图形学、物理模拟和数学可视化中点的旋转是一个基础且重要的概念。本文将使用 Python 的 Matplotlib 库通过动画直观地演示一个二维点如何绕原点进行旋转。我们将从旋转矩阵的数学原理出发逐步编写代码最终生成一个平滑的旋转动画。2. 旋转矩阵原理二维平面中一个点(x, y)绕原点逆时针旋转 θ 弧度后新坐标(x, y)可以通过旋转矩阵计算[x] [cosθ -sinθ] [x] [y] [sinθ cosθ] [y]展开后得到x x * cosθ - y * sinθy x * sinθ y * cosθ这就是我们代码中rotate函数的数学基础。3. 代码实现3.1 导入库importnumpyasnp# 导入 numpy用于数学计算三角函数、数组importmatplotlib.pyplotasplt# 导入 matplotlib 绘图库用于绘制图像frommatplotlib.animationimportFuncAnimation# 导入动画模块用于生成逐帧动画3.2 定义旋转函数# 旋转半径R2.0# 定义初始点距离原点的距离半径# 初始点 (R, 0)[x_f; y_f] [[cos(θ), -sin(θ)], [sin(θ), cos(θ)]] * [x_m; y_m]# 二维旋转矩阵defrotate(px,py,theta):将点 (px, py) 绕原点旋转 theta 弧度返回旋转后的新坐标。cnp.cos(theta)# 计算旋转角度的余弦值snp.sin(theta)# 计算旋转角度的正弦值xpx*c-py*s# 旋转公式新 x px*cosθ - py*sinθypx*spy*c# 旋转公式新 y px*sinθ py*cosθreturnx,y# 返回旋转后的坐标 (x, y)3.3 初始化画布# 创建画布fig,axplt.subplots(figsize(6,6))# 创建 6x6 英寸的画布和坐标轴对象ax.set_xlim(-R-0.4,R0.4)# 设置 x 轴显示范围留出 0.4 的边距ax.set_ylim(-R-0.4,R0.4)# 设置 y 轴显示范围留出 0.4 的边距ax.set_aspect(equal)# 设置 x、y 轴比例相等保证圆形不变形ax.grid(True,alpha0.3)# 开启网格线透明度设为 0.3ax.axhline(0,cblack,lw1)# 绘制 x 轴y0 的水平线ax.axvline(0,cblack,lw1)# 绘制 y 轴x0 的垂直线ax.set_title(2D Point Rotate Around Origin)# 设置图像标题# 绘图对象point,ax.plot([],[],ro,markersize8)# 创建红点对象初始为空尺寸 8代表旋转的点3.4 定义动画函数definit():初始化函数blit 模式下先绘制一帧空白画面。point.set_data([],[])# 红点初始为空return(point,)# 必须返回可迭代的 Artist 序列单元素元组defupdate(frame):动画每一帧的更新函数frame 为当前帧编号。thetanp.radians(frame)# 将帧编号角度值从度转换为弧度x,yrotate(R,0,theta)# 计算初始点 (R, 0) 旋转 theta 后的坐标point.set_data([x],[y])# 更新红点的位置return(point,)# 必须返回可迭代的 Artist 序列单元素元组3.5 创建并运行动画# 动画aniFuncAnimation(# 创建动画对象fig,update,framesnp.arange(0,360,2),# 帧从 0° 到 360°每 2° 一帧init_funcinit,# 初始化函数blit 模式用它绘制初始空白帧interval30,blitTrue,repeatTrue# 每帧间隔 30msblitTrue 加快渲染循环播放)plt.show()# 显示动画窗口4. 代码解析旋转矩阵rotate函数实现了二维旋转矩阵的乘法运算。动画参数framesnp.arange(0, 360, 2)生成从 0° 到 360°步长为 2° 的帧序列共 180 帧。interval30每帧间隔 30 毫秒动画速度约为 33 帧/秒。blitTrue只重绘变化的部分红点大幅提升渲染效率。repeatTrue动画播放完毕后自动循环。坐标轴设置ax.set_aspect(equal)确保 x 和 y 轴比例一致旋转轨迹呈现完美的圆形。5. 运行效果运行上述代码后会弹出一个窗口显示一个红点以原点为中心、半径为 2 的圆形轨迹匀速旋转。你可以通过修改R的值来改变旋转半径或调整frames和interval参数来改变旋转速度和流畅度。6. 扩展思考绕任意点旋转修改rotate函数先平移坐标系使旋转中心移至原点旋转后再平移回去。绘制轨迹在update函数中记录历史位置并绘制连线可直观看到圆形路径。三维旋转使用类似原理可以扩展到三维空间绕轴旋转。7. 总结本文通过一个简洁的 Python 动画示例演示了二维旋转矩阵的应用。代码结构清晰注释详细适合初学者理解旋转的数学原理和 Matplotlib 动画的基本用法。你可以在此基础上进行修改和扩展实现更复杂的图形动画效果。附importnumpyasnp# 导入 numpy用于数学计算三角函数、数组importmatplotlib.pyplotasplt# 导入 matplotlib 绘图库用于绘制图像frommatplotlib.animationimportFuncAnimation# 导入动画模块用于生成逐帧动画# 旋转半径R2.0# 定义初始点距离原点的距离半径# 初始点 (R, 0)[x_f; y_f] [[cos(θ), -sin(θ)], [sin(θ), cos(θ)]] * [x_m; y_m]# 二维旋转矩阵defrotate(px,py,theta):将点 (px, py) 绕原点旋转 theta 弧度返回旋转后的新坐标。cnp.cos(theta)# 计算旋转角度的余弦值snp.sin(theta)# 计算旋转角度的正弦值xpx*c-py*s# 旋转公式新 x px*cosθ - py*sinθypx*spy*c# 旋转公式新 y px*sinθ py*cosθreturnx,y# 返回旋转后的坐标 (x, y)# 创建画布fig,axplt.subplots(figsize(6,6))# 创建 6x6 英寸的画布和坐标轴对象ax.set_xlim(-R-0.4,R0.4)# 设置 x 轴显示范围留出 0.4 的边距ax.set_ylim(-R-0.4,R0.4)# 设置 y 轴显示范围留出 0.4 的边距ax.set_aspect(equal)# 设置 x、y 轴比例相等保证圆形不变形ax.grid(True,alpha0.3)# 开启网格线透明度设为 0.3ax.axhline(0,cblack,lw1)# 绘制 x 轴y0 的水平线ax.axvline(0,cblack,lw1)# 绘制 y 轴x0 的垂直线ax.set_title(2D Point Rotate Around Origin)# 设置图像标题# 绘图对象point,ax.plot([],[],ro,markersize8)# 创建红点对象初始为空尺寸 8代表旋转的点definit():初始化函数blit 模式下先绘制一帧空白画面。point.set_data([],[])# 红点初始为空return(point,)# 必须返回可迭代的 Artist 序列单元素元组defupdate(frame):动画每一帧的更新函数frame 为当前帧编号。thetanp.radians(frame)# 将帧编号角度值从度转换为弧度x,yrotate(R,0,theta)# 计算初始点 (R, 0) 旋转 theta 后的坐标point.set_data([x],[y])# 更新红点的位置return(point,)# 必须返回可迭代的 Artist 序列单元素元组# ani FuncAnimation(# fig, # ① 画布对象告诉动画在哪块画布上播放# update, # ② 更新函数告诉动画每帧调用哪个函数来画图# framesnp.arange(0, 360, 2), # ③ 帧序列告诉动画一共有多少帧# interval30, # ④ 时间间隔每帧之间隔多少毫秒30ms# blitTrue, # ⑤ 是否只重绘变化的部分# repeatTrue # ⑥ 播完一遍后是否循环# )# 动画aniFuncAnimation(# 创建动画对象fig,update,framesnp.arange(0,360,2),# 帧从 0° 到 360°每 2° 一帧init_funcinit,# 初始化函数blit 模式用它绘制初始空白帧interval30,blitTrue,repeatTrue# 每帧间隔 30msblitTrue 加快渲染循环播放)plt.show()# 显示动画窗口