Manim实现镜面反射特效

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

1. 实现原理

1.1. 对称点计算

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

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

python 复制代码
# 关于直线的对称点
# 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 - p

    return np.array([symmetric_point[0], symmetric_point[1], 0])

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

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

1.2. 反射动画类设计

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

python 复制代码
# 镜面反射动画类
class MirrorReflection(Animation):
    def __init__(
        self,
        mobject,
        mirror: Line = None,
        reflect_opacity=0.3,
        reflect_stroke_opacity=0.5,
        **kwargs,
    ):
        # 初始化参数
        self.original = mobject
        self.mirror = mirror if mirror else Line(LEFT, RIGHT)
        self.reflect_opacity = reflect_opacity
        self.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. 动态更新机制

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

python 复制代码
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. 使用示例

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

python 复制代码
# 使用示例
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动画增添更多的视觉魅力和专业感。

相关推荐
星哥说事3 小时前
Python自学21 - Python处理图像
python
xrkhy3 小时前
SpringBoot面试
spring boot·后端·面试
Frank_zhou3 小时前
RuoYi-Cloud-Plus 微服务架构文档
后端
西猫雷婶3 小时前
python学智能算法(三十八)|使用Numpy和PyTorch模块绘制正态分布函数图
pytorch·python·numpy
2301_764441333 小时前
使用python的加权Jaccard分析流程
开发语言·python
Java水解3 小时前
Spring Data JPA与Kingbase数据库的完美邂逅:构建高效数据持久层
后端·spring
我是华为OD~HR~栗栗呀3 小时前
22届考研(华为oD)-Java面经
java·c++·后端·python·考研·华为od·华为
Gerlat小智3 小时前
【Python精讲 03】Python核心容器:一篇通关序列(List, Tuple)、映射(Dict)与集合(Set)
windows·python·list