news 2026/8/17 20:41:43

旋转矩阵:二维点绕原点旋转

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
旋转矩阵:二维点绕原点旋转

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 定义旋转函数

# 旋转半径R=2.0# 定义初始点距离原点的距离(半径)# 初始点 (R, 0)'''[x_f; y_f] = [[cos(θ), -sin(θ)], [sin(θ), cos(θ)]] * [x_m; y_m]'''# 二维旋转矩阵defrotate(px,py,theta):"""将点 (px, py) 绕原点旋转 theta 弧度,返回旋转后的新坐标。"""c=np.cos(theta)# 计算旋转角度的余弦值s=np.sin(theta)# 计算旋转角度的正弦值x=px*c-py*s# 旋转公式:新 x = px*cosθ - py*sinθy=px*s+py*c# 旋转公式:新 y = px*sinθ + py*cosθreturnx,y# 返回旋转后的坐标 (x, y)

3.3 初始化画布

# 创建画布fig,ax=plt.subplots(figsize=(6,6))# 创建 6x6 英寸的画布和坐标轴对象ax.set_xlim(-R-0.4,R+0.4)# 设置 x 轴显示范围,留出 0.4 的边距ax.set_ylim(-R-0.4,R+0.4)# 设置 y 轴显示范围,留出 0.4 的边距ax.set_aspect("equal")# 设置 x、y 轴比例相等,保证圆形不变形ax.grid(True,alpha=0.3)# 开启网格线,透明度设为 0.3ax.axhline(0,c="black",lw=1)# 绘制 x 轴(y=0 的水平线)ax.axvline(0,c="black",lw=1)# 绘制 y 轴(x=0 的垂直线)ax.set_title("2D Point Rotate Around Origin")# 设置图像标题# 绘图对象point,=ax.plot([],[],"ro",markersize=8)# 创建红点对象,初始为空,尺寸 8,代表旋转的点

3.4 定义动画函数

definit():"""初始化函数:blit 模式下先绘制一帧空白画面。"""point.set_data([],[])# 红点初始为空return(point,)# 必须返回可迭代的 Artist 序列(单元素元组)defupdate(frame):"""动画每一帧的更新函数,frame 为当前帧编号。"""theta=np.radians(frame)# 将帧编号(角度值)从度转换为弧度x,y=rotate(R,0,theta)# 计算初始点 (R, 0) 旋转 theta 后的坐标point.set_data([x],[y])# 更新红点的位置return(point,)# 必须返回可迭代的 Artist 序列(单元素元组)

3.5 创建并运行动画

# 动画ani=FuncAnimation(# 创建动画对象fig,update,frames=np.arange(0,360,2),# 帧从 0° 到 360°,每 2° 一帧init_func=init,# 初始化函数:blit 模式用它绘制初始空白帧interval=30,blit=True,repeat=True# 每帧间隔 30ms;blit=True 加快渲染;循环播放)plt.show()# 显示动画窗口

4. 代码解析

  1. 旋转矩阵rotate函数实现了二维旋转矩阵的乘法运算。
  2. 动画参数
    • frames=np.arange(0, 360, 2):生成从 0° 到 360°,步长为 2° 的帧序列,共 180 帧。
    • interval=30:每帧间隔 30 毫秒,动画速度约为 33 帧/秒。
    • blit=True:只重绘变化的部分(红点),大幅提升渲染效率。
    • repeat=True:动画播放完毕后自动循环。
  3. 坐标轴设置ax.set_aspect("equal")确保 x 和 y 轴比例一致,旋转轨迹呈现完美的圆形。

5. 运行效果

运行上述代码后,会弹出一个窗口,显示一个红点以原点为中心、半径为 2 的圆形轨迹匀速旋转。你可以通过修改R的值来改变旋转半径,或调整framesinterval参数来改变旋转速度和流畅度。

6. 扩展思考

  • 绕任意点旋转:修改rotate函数,先平移坐标系使旋转中心移至原点,旋转后再平移回去。
  • 绘制轨迹:在update函数中记录历史位置并绘制连线,可直观看到圆形路径。
  • 三维旋转:使用类似原理,可以扩展到三维空间绕轴旋转。

7. 总结

本文通过一个简洁的 Python 动画示例,演示了二维旋转矩阵的应用。代码结构清晰,注释详细,适合初学者理解旋转的数学原理和 Matplotlib 动画的基本用法。你可以在此基础上进行修改和扩展,实现更复杂的图形动画效果。

importnumpyasnp# 导入 numpy,用于数学计算(三角函数、数组)importmatplotlib.pyplotasplt# 导入 matplotlib 绘图库,用于绘制图像frommatplotlib.animationimportFuncAnimation# 导入动画模块,用于生成逐帧动画# 旋转半径R=2.0# 定义初始点距离原点的距离(半径)# 初始点 (R, 0)'''[x_f; y_f] = [[cos(θ), -sin(θ)], [sin(θ), cos(θ)]] * [x_m; y_m]'''# 二维旋转矩阵defrotate(px,py,theta):"""将点 (px, py) 绕原点旋转 theta 弧度,返回旋转后的新坐标。"""c=np.cos(theta)# 计算旋转角度的余弦值s=np.sin(theta)# 计算旋转角度的正弦值x=px*c-py*s# 旋转公式:新 x = px*cosθ - py*sinθy=px*s+py*c# 旋转公式:新 y = px*sinθ + py*cosθreturnx,y# 返回旋转后的坐标 (x, y)# 创建画布fig,ax=plt.subplots(figsize=(6,6))# 创建 6x6 英寸的画布和坐标轴对象ax.set_xlim(-R-0.4,R+0.4)# 设置 x 轴显示范围,留出 0.4 的边距ax.set_ylim(-R-0.4,R+0.4)# 设置 y 轴显示范围,留出 0.4 的边距ax.set_aspect("equal")# 设置 x、y 轴比例相等,保证圆形不变形ax.grid(True,alpha=0.3)# 开启网格线,透明度设为 0.3ax.axhline(0,c="black",lw=1)# 绘制 x 轴(y=0 的水平线)ax.axvline(0,c="black",lw=1)# 绘制 y 轴(x=0 的垂直线)ax.set_title("2D Point Rotate Around Origin")# 设置图像标题# 绘图对象point,=ax.plot([],[],"ro",markersize=8)# 创建红点对象,初始为空,尺寸 8,代表旋转的点definit():"""初始化函数:blit 模式下先绘制一帧空白画面。"""point.set_data([],[])# 红点初始为空return(point,)# 必须返回可迭代的 Artist 序列(单元素元组)defupdate(frame):"""动画每一帧的更新函数,frame 为当前帧编号。"""theta=np.radians(frame)# 将帧编号(角度值)从度转换为弧度x,y=rotate(R,0,theta)# 计算初始点 (R, 0) 旋转 theta 后的坐标point.set_data([x],[y])# 更新红点的位置return(point,)# 必须返回可迭代的 Artist 序列(单元素元组)# ani = FuncAnimation(# fig, # ① 画布对象:告诉动画"在哪块画布上播放"# update, # ② 更新函数:告诉动画"每帧调用哪个函数来画图"# frames=np.arange(0, 360, 2), # ③ 帧序列:告诉动画"一共有多少帧"# interval=30, # ④ 时间间隔:每帧之间隔多少毫秒(30ms)# blit=True, # ⑤ 是否只重绘变化的部分# repeat=True # ⑥ 播完一遍后是否循环# )# 动画ani=FuncAnimation(# 创建动画对象fig,update,frames=np.arange(0,360,2),# 帧从 0° 到 360°,每 2° 一帧init_func=init,# 初始化函数:blit 模式用它绘制初始空白帧interval=30,blit=True,repeat=True# 每帧间隔 30ms;blit=True 加快渲染;循环播放)plt.show()# 显示动画窗口
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/17 20:41:40

JDBC深度解析:从核心架构到生产环境实战优化

1. 项目概述:为什么今天还要深挖JDBC? 如果你在Java开发这条路上走了有些年头,可能会觉得JDBC是个“老古董”——Spring Data JPA、MyBatis Plus这些框架用起来多香,谁还愿意去写那些冗长的 Connection 、 Statement 和 Resu…

作者头像 李华
网站建设 2026/8/17 20:39:56

从三六零零元转让哪吒汽车股权看对赌协议与商业博弈

1. 从“零元”交易看商业世界的非典型操作最近,一则关于三六零公司“零元”转让其持有的哪吒汽车部分股权的新闻,在商业和创投圈里激起了不小的水花。很多人第一眼看到“零元”、“甩卖”、“违约”这些字眼,直觉反应就是:这肯定是…

作者头像 李华
网站建设 2026/8/17 20:37:45

PowerBI主题模板完整实战指南:3步用JSON统一报表全部图表样式

PowerBI主题模板完整实战指南:3步用JSON统一报表全部图表样式 【免费下载链接】PowerBI-ThemeTemplates Snippets for assembling Power BI Themes 项目地址: https://gitcode.com/gh_mirrors/po/PowerBI-ThemeTemplates 你算过吗?做一份 Power B…

作者头像 李华
网站建设 2026/8/17 20:37:11

SteamAutoCrack完整上手教程:三步让Steam游戏离线也能玩

SteamAutoCrack完整上手教程:三步让Steam游戏离线也能玩 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack 前阵子出差,高铁上打开笔记本想玩刚买的两款游戏&#…

作者头像 李华
网站建设 2026/8/17 20:35:52

蚂蚁森林自动收能量效率工具:3步配置,解锁全天候自动收取

蚂蚁森林自动收能量效率工具:3步配置,解锁全天候自动收取 【免费下载链接】alipay_autojs 最最最简单的蚂蚁森林自动收能量脚本 项目地址: https://gitcode.com/gh_mirrors/al/alipay_autojs 早上7:12,闹钟第二次响起。小陈眯着眼摸到…

作者头像 李华
网站建设 2026/8/17 20:34:31

汽车设计解析:从申报图看懂中期改款背后的工程与商业逻辑

1. 从申报图到量产车:一次外观设计的“外科手术”最近,新款祺智EV的申报图在网络上曝光,这就像汽车圈里的一次“内部文件泄露”,让所有关注这款车的人提前看到了它即将到来的新面貌。对于普通消费者来说,这可能只是几张…

作者头像 李华