You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Manim中将线条移回初始位置?

问题

我有4条组成矩形的线条,想在场景中先将这些线条互相移开,展示它们并非彼此连接,之后再移回初始位置重新组成矩形。请问是否无需新建目标位置就能实现线条复位?

现有代码

from manim import *

bufferCoordinates = [
    [5, -1.65180767, 0.0],
    [3.67578217, -3.77055619, 0.0],
    [-5.0, 1.65180767, 0.0],
    [-3.67578217, 3.77055619, 0.0],
]

config.frame_width = 18
config.frame_height = 12

class getLSWgeoms(ZoomedScene):
    def construct(self):
        
        # Polygon
        buffer = Polygon(*bufferCoordinates)
        buffer.set_fill(PINK, opacity=0.5)

        # Single Lines
        bufferline1 = Line(*[[5, -1.65180767, 0.0], [3.67578217, -3.77055619, 0.0]])
        bufferline1.generate_target()
        bufferline1.target.move_to(5.0 * RIGHT + 3 * DOWN)

        bufferline2 = Line(*[[3.67578217, -3.77055619, 0.0], [-5.0, 1.65180767, 0.0]])
        bufferline2.generate_target()
        bufferline2.target.move_to(1.5 * DOWN + 1 * LEFT)

        bufferline3 = Line(*[[-5.0, 1.65180767, 0.0], [-3.67578217, 3.77055619, 0.0]])
        bufferline3.generate_target()
        bufferline3.target.move_to(5 * LEFT + 3 * UP)

        bufferline4 = Line(*[[-3.67578217, 3.77055619, 0.0],[5, -1.65180767, 0.0]])
        bufferline4.generate_target()
        bufferline4.target.move_to(1.5 * UP + 1 * RIGHT)
        
        # Play Scenes
        self.play(FadeIn(buffer), run_time=1)
        self.play(
            MoveToTarget(bufferline1),
            MoveToTarget(bufferline2),
            MoveToTarget(bufferline3),
            MoveToTarget(bufferline4),
            run_time=3
        )

解答

完全可以不用新建目标位置实现复位,以下是两种简单可行的方法:

方法一:保存初始状态副本

在创建线条后立即保存每个线条的初始副本,后续通过Transform动画直接恢复到初始状态:

from manim import *

bufferCoordinates = [
    [5, -1.65180767, 0.0],
    [3.67578217, -3.77055619, 0.0],
    [-5.0, 1.65180767, 0.0],
    [-3.67578217, 3.77055619, 0.0],
]

config.frame_width = 18
config.frame_height = 12

class getLSWgeoms(ZoomedScene):
    def construct(self):
        
        # Polygon
        buffer = Polygon(*bufferCoordinates)
        buffer.set_fill(PINK, opacity=0.5)

        # Single Lines
        bufferline1 = Line(*[[5, -1.65180767, 0.0], [3.67578217, -3.77055619, 0.0]])
        bufferline1_copy = bufferline1.copy()  # 保存初始状态副本
        bufferline1.generate_target()
        bufferline1.target.move_to(5.0 * RIGHT + 3 * DOWN)

        bufferline2 = Line(*[[3.67578217, -3.77055619, 0.0], [-5.0, 1.65180767, 0.0]])
        bufferline2_copy = bufferline2.copy()
        bufferline2.generate_target()
        bufferline2.target.move_to(1.5 * DOWN + 1 * LEFT)

        bufferline3 = Line(*[[-5.0, 1.65180767, 0.0], [-3.67578217, 3.77055619, 0.0]])
        bufferline3_copy = bufferline3.copy()
        bufferline3.generate_target()
        bufferline3.target.move_to(5 * LEFT + 3 * UP)

        bufferline4 = Line(*[[-3.67578217, 3.77055619, 0.0],[5, -1.65180767, 0.0]])
        bufferline4_copy = bufferline4.copy()
        bufferline4.generate_target()
        bufferline4.target.move_to(1.5 * UP + 1 * RIGHT)
        
        # Play Scenes
        self.play(FadeIn(buffer), run_time=1)
        self.play(
            MoveToTarget(bufferline1),
            MoveToTarget(bufferline2),
            MoveToTarget(bufferline3),
            MoveToTarget(bufferline4),
            run_time=3
        )
        # 执行复位动画
        self.play(
            Transform(bufferline1, bufferline1_copy),
            Transform(bufferline2, bufferline2_copy),
            Transform(bufferline3, bufferline3_copy),
            Transform(bufferline4, bufferline4_copy),
            run_time=3
        )

方法二:记录初始端点坐标,用put_start_and_end_on复位

提前记录每条线条的初始端点坐标,后续调用put_start_and_end_on方法配合animate语法实现复位:

from manim import *

bufferCoordinates = [
    [5, -1.65180767, 0.0],
    [3.67578217, -3.77055619, 0.0],
    [-5.0, 1.65180767, 0.0],
    [-3.67578217, 3.77055619, 0.0],
]

config.frame_width = 18
config.frame_height = 12

class getLSWgeoms(ZoomedScene):
    def construct(self):
        
        # Polygon
        buffer = Polygon(*bufferCoordinates)
        buffer.set_fill(PINK, opacity=0.5)

        # 提前记录所有线条的初始端点坐标
        line_initial_coords = [
            [[5, -1.65180767, 0.0], [3.67578217, -3.77055619, 0.0]],
            [[3.67578217, -3.77055619, 0.0], [-5.0, 1.65180767, 0.0]],
            [[-5.0, 1.65180767, 0.0], [-3.67578217, 3.77055619, 0.0]],
            [[-3.67578217, 3.77055619, 0.0],[5, -1.65180767, 0.0]]
        ]

        # Single Lines
        bufferline1 = Line(*line_initial_coords[0])
        bufferline1.generate_target()
        bufferline1.target.move_to(5.0 * RIGHT + 3 * DOWN)

        bufferline2 = Line(*line_initial_coords[1])
        bufferline2.generate_target()
        bufferline2.target.move_to(1.5 * DOWN + 1 * LEFT)

        bufferline3 = Line(*line_initial_coords[2])
        bufferline3.generate_target()
        bufferline3.target.move_to(5 * LEFT + 3 * UP)

        bufferline4 = Line(*line_initial_coords[3])
        bufferline4.generate_target()
        bufferline4.target.move_to(1.5 * UP + 1 * RIGHT)
        
        # Play Scenes
        self.play(FadeIn(buffer), run_time=1)
        self.play(
            MoveToTarget(bufferline1),
            MoveToTarget(bufferline2),
            MoveToTarget(bufferline3),
            MoveToTarget(bufferline4),
            run_time=3
        )
        # 执行复位动画
        self.play(
            bufferline1.animate.put_start_and_end_on(*line_initial_coords[0]),
            bufferline2.animate.put_start_and_end_on(*line_initial_coords[1]),
            bufferline3.animate.put_start_and_end_on(*line_initial_coords[2]),
            bufferline4.animate.put_start_and_end_on(*line_initial_coords[3]),
            run_time=3
        )

两种方法都不需要为复位操作额外创建target对象,直接利用初始状态或坐标就能让线条回到原位。

内容的提问来源于stack exchange,提问作者i.i.k.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:36:07