自定义动画类的结构class TwistAnimation(Animation): def __init__( self, mobject, centerORIGIN, twist_angleTAU, strength1.0, directionclockwise, **kwargs ): super().__init__(mobject, **kwargs) # 存储初始状态以便在动画过程中重置 self.center center self.twist_angle twist_angle self.strength strength self.direction direction # 根据方向调整扭曲角度 if direction counterclockwise: self.twist_angle -self.twist_angle这个类定义了几个关键参数mobject要进行扭曲的Manim对象center扭曲中心点默认为原点twist_angle总扭曲角度默认为TAU(360度)strength扭曲强度默认为1.0direction扭曲方向可以是clockwise(顺时针)或counterclockwise(逆时针)扭曲算法的核心实现扭曲效果的核心在于interpolate_mobject方法它在动画的每一帧被调用根据当前的进度alpha更新对象的形状def interpolate_mobject(self, alpha): # 重置对象到初始状态 self.mobject.become(self.starting_mobject) # 计算当前的扭曲角度 current_twist_angle alpha * self.twist_angle # 获取对象的所有点 points self.mobject.points # 对每个点应用扭曲变换 for i in range(len(points)): # 计算点相对于中心的位置 point points[i] rel_point point - self.center # 计算点到中心的距离 distance np.linalg.norm(rel_point) # 如果点在中心则不进行变换 if distance 0: continue # 计算点的极角 angle np.arctan2(rel_point[1], rel_point[0]) # 计算扭曲后的角度距离中心越远扭曲角度越大 twisted_angle angle current_twist_angle * (distance * self.strength) # 计算扭曲后的坐标 twisted_x self.center[0] distance * np.cos(twisted_angle) twisted_y self.center[1] distance * np.sin(twisted_angle) # 更新点的位置 points[i] np.array([twisted_x, twisted_y, point[2]]) # 将更新后的点应用到对象上 self.mobject.set_points(points)这个算法的核心思想是将对象上的每个点转换为相对于扭曲中心的极坐标根据点到中心的距离计算扭曲角度距离越远扭曲越大将扭曲后的极坐标转换回笛卡尔坐标更新对象上所有点的位置这种实现方式使得扭曲效果非常自然尤其是对于几何形状对象。使用示例代码中提供了三个示例场景展示了如何使用这个扭曲特效。基本扭曲效果Example01类展示了基本的扭曲效果包括顺时针和逆时针扭曲class Example01(Scene): 基本的扭曲效果 def construct(self): # 创建一个矩形作为扭曲对象 rect Rectangle(width4, height2, colorBLUE, fill_opacity0.5) # 添加扭曲动画 self.play(Create(rect)) self.wait() self.play(TwistAnimation(rect, run_time2)) self.play(TwistAnimation(rect, twist_angle-TAU, run_time2)) # 反向扭曲 self.wait()这个示例创建了一个蓝色矩形然后先应用顺时针扭曲再应用逆时针扭曲。不同扭曲中心的效果Example02类展示了使用不同扭曲中心的效果class Example02(Scene): 不同扭曲中心的效果 def construct(self): # 创建多个对象并设置不同的扭曲中心 circle1 Circle(radius0.8, colorRED, fill_opacity0.5) circle1.shift(LEFT * 2) circle2 Circle(radius0.8, colorGREEN, fill_opacity0.5) circle3 Circle(radius0.8, colorBLUE, fill_opacity0.5) circle3.shift(RIGHT * 2) # 添加中心标记 center_marker1 Dot(colorWHITE).shift(LEFT * 3) center_marker3 Dot(colorWHITE).shift(RIGHT * 3) # 添加对象到场景 self.play(Create(circle1), Create(circle2), Create(circle3)) self.play(Create(center_marker1), Create(center_marker3)) self.wait() # 应用扭曲动画使用不同的中心 self.play( TwistAnimation(circle1, centercenter_marker1.get_center(), run_time2), TwistAnimation(circle2, centerORIGIN, run_time2), TwistAnimation(circle3, centercenter_marker3.get_center(), run_time2), ) self.wait()这个示例创建了三个不同颜色的圆并分别使用不同的中心点进行扭曲直观地展示了扭曲中心对效果的影响。不同扭曲强度的效果
旋转扭曲特效的核心是通过修改对象上每个点的坐标来实现扭曲效果。
发布时间:2026/7/1 1:44:03
自定义动画类的结构class TwistAnimation(Animation): def __init__( self, mobject, centerORIGIN, twist_angleTAU, strength1.0, directionclockwise, **kwargs ): super().__init__(mobject, **kwargs) # 存储初始状态以便在动画过程中重置 self.center center self.twist_angle twist_angle self.strength strength self.direction direction # 根据方向调整扭曲角度 if direction counterclockwise: self.twist_angle -self.twist_angle这个类定义了几个关键参数mobject要进行扭曲的Manim对象center扭曲中心点默认为原点twist_angle总扭曲角度默认为TAU(360度)strength扭曲强度默认为1.0direction扭曲方向可以是clockwise(顺时针)或counterclockwise(逆时针)扭曲算法的核心实现扭曲效果的核心在于interpolate_mobject方法它在动画的每一帧被调用根据当前的进度alpha更新对象的形状def interpolate_mobject(self, alpha): # 重置对象到初始状态 self.mobject.become(self.starting_mobject) # 计算当前的扭曲角度 current_twist_angle alpha * self.twist_angle # 获取对象的所有点 points self.mobject.points # 对每个点应用扭曲变换 for i in range(len(points)): # 计算点相对于中心的位置 point points[i] rel_point point - self.center # 计算点到中心的距离 distance np.linalg.norm(rel_point) # 如果点在中心则不进行变换 if distance 0: continue # 计算点的极角 angle np.arctan2(rel_point[1], rel_point[0]) # 计算扭曲后的角度距离中心越远扭曲角度越大 twisted_angle angle current_twist_angle * (distance * self.strength) # 计算扭曲后的坐标 twisted_x self.center[0] distance * np.cos(twisted_angle) twisted_y self.center[1] distance * np.sin(twisted_angle) # 更新点的位置 points[i] np.array([twisted_x, twisted_y, point[2]]) # 将更新后的点应用到对象上 self.mobject.set_points(points)这个算法的核心思想是将对象上的每个点转换为相对于扭曲中心的极坐标根据点到中心的距离计算扭曲角度距离越远扭曲越大将扭曲后的极坐标转换回笛卡尔坐标更新对象上所有点的位置这种实现方式使得扭曲效果非常自然尤其是对于几何形状对象。使用示例代码中提供了三个示例场景展示了如何使用这个扭曲特效。基本扭曲效果Example01类展示了基本的扭曲效果包括顺时针和逆时针扭曲class Example01(Scene): 基本的扭曲效果 def construct(self): # 创建一个矩形作为扭曲对象 rect Rectangle(width4, height2, colorBLUE, fill_opacity0.5) # 添加扭曲动画 self.play(Create(rect)) self.wait() self.play(TwistAnimation(rect, run_time2)) self.play(TwistAnimation(rect, twist_angle-TAU, run_time2)) # 反向扭曲 self.wait()这个示例创建了一个蓝色矩形然后先应用顺时针扭曲再应用逆时针扭曲。不同扭曲中心的效果Example02类展示了使用不同扭曲中心的效果class Example02(Scene): 不同扭曲中心的效果 def construct(self): # 创建多个对象并设置不同的扭曲中心 circle1 Circle(radius0.8, colorRED, fill_opacity0.5) circle1.shift(LEFT * 2) circle2 Circle(radius0.8, colorGREEN, fill_opacity0.5) circle3 Circle(radius0.8, colorBLUE, fill_opacity0.5) circle3.shift(RIGHT * 2) # 添加中心标记 center_marker1 Dot(colorWHITE).shift(LEFT * 3) center_marker3 Dot(colorWHITE).shift(RIGHT * 3) # 添加对象到场景 self.play(Create(circle1), Create(circle2), Create(circle3)) self.play(Create(center_marker1), Create(center_marker3)) self.wait() # 应用扭曲动画使用不同的中心 self.play( TwistAnimation(circle1, centercenter_marker1.get_center(), run_time2), TwistAnimation(circle2, centerORIGIN, run_time2), TwistAnimation(circle3, centercenter_marker3.get_center(), run_time2), ) self.wait()这个示例创建了三个不同颜色的圆并分别使用不同的中心点进行扭曲直观地展示了扭曲中心对效果的影响。不同扭曲强度的效果