ZhangZhihui's Blog  

https://docs.manim.community/en/stable/tutorials/quickstart.html

 

class DifferentRotations(Scene):
    def construct(self):
        left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
        right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
        self.play(
            left_square.animate.rotate(PI), Rotate(right_square, angle=PI), run_time=2
        )
        self.wait()

这个出来的动画效果是左边的square先变小再变回来的大小,并没有旋转,为什么?

 

这是一个非常经典的 Manim 陷阱。

你看到的“变小再变大”其实是线性插值导致的视觉错觉。在 Manim 中,.animate 默认寻找的是对象状态之间的“最短路径”。

为什么 .animate.rotate(PI) 没有旋转?

当你执行 left_square.animate.rotate(PI) 时:

  1. 起始状态:正方形的四个顶点位置。

  2. 终止状态:正方形旋转 $180^\circ$ ($\pi$) 后的顶点位置。

  3. 问题所在:由于正方形是对称的,旋转 $180^\circ$ 后的顶点坐标与原坐标在数学上是重合的(或者说是镜像对称的)。

  4. 动画路径:.animate 并不理解“旋转过程”,它只看“起点”和“终点”。既然终点和起点看起来一样,它会尝试对中间的数值进行补间。对于正方形来说,这个补间过程在视觉上表现为:图形向中心坍缩(变小)然后又拉伸回来(变大),而不是圆周运动。

为什么右边的 Rotate 是正常的?

Rotate(right_square, angle=PI) 是一个具体的动画类(Animation Class),而不是简单的属性插值。

  • 它内部定义了旋转的数学路径。

  • 它会强制对象绕着中心点沿着圆弧轨迹运动,而不是简单地计算顶点的直线位移。


如何修复左边的动画?

如果你坚持要使用 .animate 语法,你需要给它一个“中间点”,或者明确旋转的方式。但最简单且最推荐的方法有以下两种:

方法一:使用 Rotate 类(推荐)

就像你对右边正方形做的那样,这是处理旋转最稳健的方式。

方法二:使用 about_point(强制弧线路径)

如果你想让 .animate 表现得更像旋转,虽然在 $180^\circ$ 时依然可能出问题,但通常我们会这样写:

Python
 
self.play(left_square.animate.rotate(PI/2)) # 分两次旋转 90 度

方法三:改用位移插值外的属性(如果支持)

但在 Manim 社区版中,最标准的解决方案就是区分 状态插值 (.animate) 和 过程动画 (Rotate)。

总结建议

  • .animate:适用于位置移动 (.shift)、颜色改变 (.set_color)、缩放 (.scale) 等终点明确且路径简单的变换。

  • Rotate / ClockwiseTransform:专门用于旋转,特别是涉及到 $180^\circ$ 或 $360^\circ$ 这种对称角度时,必须使用这些专属动画类。

你的代码中,右边的 Rotate(right_square, angle=PI) 才是旋转动画的“正确打开方式”。

 

posted on 2026-05-13 22:16  ZhangZhihuiAAA  阅读(35)  评论(0)    收藏  举报