I have 4 lines making up a rectangle. In the scene I want to show, that the lines are not attached to each other and so I move them a little bit away from each other, and then I want to move them back to their original position (making up the rectangle). Is there a way to move them to their original position without creating a new target position?
This is my code so far:
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
)
Simple solution using save_state()
and Restore()
:
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.save_state()
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.save_state()
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.save_state()
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.save_state()
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.wait()
self.play(Restore(bufferline1),Restore(bufferline2),Restore(bufferline3),Restore(bufferline4), )
self.wait()
Btw, using the target
functions here is a bit more complicated than necessary imo, but maybe this is just because this is mwe. Also, your bufferlines*
will appear directly in the scene when they will be moved, they are not created or sth. similar before.
UPDATE: Here is an answer which is more how I would have done it.
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],
[5, -1.65180767, 0.0],
]
config.frame_width = 18
config.frame_height = 12
class getLSWgeoms(ZoomedScene):
def construct(self):
# Polygon
buffer = Polygon(*bufferCoordinates[:4])
buffer.set_fill(PINK, opacity=0.5)
# Single Lines
bufferlines = VGroup(
*[
Line(start, end)
for start, end in zip(bufferCoordinates[:4], bufferCoordinates[1:])
]
)
bufferlines.save_state()
# Play Scenes
self.play(FadeIn(buffer), run_time=1)
self.wait()
self.play(Create(bufferlines))
self.wait()
self.play(
bufferlines[0].animate.move_to(5.0 * RIGHT + 3 * DOWN),
bufferlines[1].animate.move_to(1.5 * DOWN + 1 * LEFT),
bufferlines[2].animate.move_to(5 * LEFT + 3 * UP),
bufferlines[3].animate.move_to(1.5 * UP + 1 * RIGHT),
run_time=3,
)
self.wait()
self.play(Restore(bufferlines))
self.wait()
I'm not a python expert, so the list operations could maybe even more optimized. Instead of animating each bufferline you could also use an AnimationGroup
, but I don't use it that often. I think like this it is more readable. Also, you could use shift()
instead of move_to()
but I was too lazy to do the recalculation :D.