如何在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.
相关产品推荐
相关产品推荐

