当前位置: 首页 > news >正文

Manim实现镜面反射特效

本文将介绍如何使用ManimCE框架实现镜面反射特效,让你的动画更加生动有趣。

1. 实现原理

1.1. 对称点计算

实现镜面反射的核心是计算点关于直线的对称点。

代码中的symmetry_point函数通过向量投影的方法计算对称点:

# 关于直线的对称点
# p1和p2在直线l上,计算p关于l的对称点
def symmetry_point(p1, p2, p):"""计算点p关于由两点p1和p2确定的直线的对称点参数:p1, p2 : 直线上的两点 (numpy array or list)p : 直线外的点 (numpy array or list)返回:对称点坐标 (numpy array)"""# 转换为numpy数组确保计算正确p1 = np.array(p1)p2 = np.array(p2)p = np.array(p)# 计算直线的方向向量direction = p2 - p1# 计算从p1到p的向量vec_p1p = p - p1# 计算投影长度(点p在直线上的投影点到p1的距离)proj_length = np.dot(vec_p1p, direction) / np.dot(direction, direction)# 计算点p在直线上的投影点projection = p1 + proj_length * direction# 对称点 = 2 * 投影点 - 原点symmetric_point = 2 * projection - preturn np.array([symmetric_point[0], symmetric_point[1], 0])

这个函数使用了向量投影的数学原理,先找到点在直线上的投影,然后根据投影点计算对称点。具体步骤是:

  1. 计算直线的方向向量
  2. 计算从直线上一点到目标点的向量
  3. 计算该向量在直线方向上的投影长度
  4. 找到投影点坐标
  5. 通过公式 2 * 投影点 - 原点 计算对称点

1.2. 反射动画类设计

MirrorReflection 类继承自Manim的 Animation 类,用于创建和管理镜面反射效果:

# 镜面反射动画类
class MirrorReflection(Animation):def __init__(self,mobject,mirror: Line = None,reflect_opacity=0.3,reflect_stroke_opacity=0.5,**kwargs,):# 初始化参数self.original = mobjectself.mirror = mirror if mirror else Line(LEFT, RIGHT)self.reflect_opacity = reflect_opacityself.reflect_stroke_opacity = reflect_stroke_opacity# 创建反射对象并设置初始属性self.reflection = mobject.copy()self._update_reflection_position()self.reflection.set_fill(opacity=self.reflect_opacity * mobject.get_fill_opacity())self.reflection.set_stroke(opacity=self.reflect_stroke_opacity * mobject.get_stroke_opacity())# 添加动态更新器self.reflection.add_updater(self._update_reflection)super().__init__(mobject, **kwargs)

1.3. 动态更新机制

为了确保反射效果能够跟随原始对象的变化而实时更新,代码实现了几个关键方法:

def _update_reflection_position(self):"""更新反射对象的位置"""points = self.original.get_points()new_points = []p1, p2 = self.mirror.get_start(), self.mirror.get_end()for p in points:# 使用对称点计算函数计算每个点的反射位置new_points.append(symmetry_point(p1, p2, p))# 应用新位置self.reflection.set_points(new_points)def _update_reflection(self, reflection_mobject):"""更新反射对象的属性"""# 重新创建反射对象并应用垂直翻转temp_reflection = self.original.copy()reflection_mobject.become(temp_reflection)# 更新反射对象位置和透明度self._update_reflection_position()reflection_mobject.set_fill(opacity=self.reflect_opacity * self.original.get_fill_opacity())reflection_mobject.set_stroke(opacity=self.reflect_stroke_opacity * self.original.get_stroke_opacity())

这些方法确保了无论原始对象如何移动、缩放或旋转,反射效果都会相应地更新,保持视觉上的一致性。

2. 使用示例

让我们看看如何在实际场景中使用这个镜面反射特效:

# 使用示例
class Example(Scene):def construct(self):# 创建三角形对象triangle = Triangle(color=BLUE)triangle.shift(2 * LEFT)# 创建垂直镜面mirror = Line(UP * 3, DOWN * 3, color=WHITE)# 创建镜面反射动画mirror_reflection = MirrorReflection(triangle, mirror=mirror)reflection = mirror_reflection.create_reflection_mobject()# 添加到场景self.add(mirror, triangle, reflection)self.wait()# 动画演示self.play(triangle.animate.shift(UP))self.wait()self.play(triangle.animate.scale(1.5))self.wait()self.play(triangle.animate.shift(DOWN))self.wait()self.play(Rotate(triangle, angle=PI))self.wait()

使用步骤非常简单:

  1. 创建需要添加反射效果的原始对象(这里是一个蓝色三角形)
  2. 创建镜面(这里是一条白色垂直线)
  3. 创建MirrorReflection实例,并传入原始对象和镜面
  4. 通过create_reflection_mobject()方法获取反射对象
  5. 将原始对象、镜面和反射对象添加到场景中
  6. 对原始对象执行各种动画操作,观察反射效果的实时更新

在这个例子中,我们演示了对象的上移、缩放、下移和旋转四种操作,反射效果都会实时跟随更新,保持与原始对象的对称关系。

3. 总结

3.1. 特效特点

这个镜面反射特效具有以下特点:

  1. 实时更新:无论原始对象如何变换,反射效果都会实时更新,保持视觉一致性
  2. 高度可定制:可以调整反射对象的填充透明度和描边透明度,创建不同的视觉效果
  3. 灵活的镜面设置:可以自定义镜面的位置、方向和样式,适应不同场景需求
  4. 易用性:封装成了独立的动画类,使用简单,只需几行代码就能添加专业的反射效果

3.2. 使用场景

镜面反射特效适用于多种场景:

  1. 数学教学:用于几何对称、坐标系变换等概念的可视化教学
  2. 物理模拟:模拟光的反射、镜像对称等物理现象
  3. 艺术效果:为动画添加美感和层次感,提升视觉吸引力
  4. 交互演示:用于展示对称关系、变换过程等
  5. Logo和品牌展示:创建镜像效果的动态Logo动画

通过这个简单而强大的镜面反射特效,可以为你的Manim动画增添更多的视觉魅力和专业感。

http://www.rkmt.cn/news/10941.html

相关文章:

  • 一些常用的网站
  • systemd-nspawn容器体积精简和桥接网络实战
  • 运维自动化工具Ansible大总结20250914 - 教程
  • 企业微信客服API模式接入第三方客服系统,对接大模型AI智能体
  • 深入解析:B树与B+树的原理区别应用
  • RHEL7/CentOS7 install NVIDIA drivers and CUDA
  • 浅谈 Burnside 和 Polya 的证明
  • 在Windows10 Edge浏览器里安装DeepSider大模型插件来免费运用gpt-4o、NanoBanana等AI大模型
  • 【杂记】原 hack
  • 124
  • 我的笔记记录方案
  • iOS Provisioning Profile 证书 描述文件
  • 告别多工具切换的低效时代:PandaWiki如何无缝集成企业现有工作流?
  • 压垮项目经理的“三座大山”:时间、成本、质量的生存法则与破局工具
  • 学习 React 前,你必须掌握的 10 个 JavaScript 核心概念
  • 二维下标极大数组(二维 map)
  • CF932E Team Work
  • KDL - 金山云数据湖系统参数
  • streamlit构建dashboard
  • vscode中element-plus组件无属性提示
  • minio集群搭建
  • 破局 “节能不省钱” 悖论:开源 EMS 生态如何让中小企业用 1/3 成本实现能效跃升?
  • 深入解析:Django事务
  • 视频汇聚平台EasyCVR如何构建智慧农业监控监管系统?
  • 继续 Vibe Coding 撸工具:Markdown写作 + 一键发布
  • 基于衍射神经网络的光学高速粒子分类体系A1(未做完)
  • LVGL移植到STM32F4出现无法运行的问题
  • 题目记录(Before NOIP2025 ver)
  • 78-材料可视化-折线图
  • 完整教程:Redis的java客户端(SpringDataRedis)