Search code examples
pythontransformmanim

Transform function & .animate in Manim


The task that I'm trying to do is as follows:

  1. Get the coordinate plane & label the coordinates.
  2. Plot a square (with a dot at its center) and make it shift around to a couple of different locations
  3. Now while the dot is at a random coordinate (say: [2, 3, 0]) then transform it into a circle, but make sure that the dot still remains at the center of the circle (earlier a square)
  4. Shift this transformed circle to different locations (just like in pt. 2)

I've managed to code the following:

from manim import *

class AnimateOne(Scene):
def construct(self):
    grid = NumberPlane()
    grid.add_coordinates()

    sq = Square(color=BLUE, fill_opacity=0.5)
    cr = Circle(radius=0.5, color=GREEN, fill_opacity=0.5)
    dot = Dot(color=RED)

    box = VGroup(sq, dot)
    round_box = VGroup(cr, dot)

    self.play(Create(grid, run_time=3, lag_ratio=0.8))
    self.play(Create(box))

    # move box around
    self.play(box.animate.shift(2 * RIGHT), run_time=2,)
    self.play(box.animate.shift(3 * UP), run_time=2,)

    self.play(Transform(box, round_box))
    
    self.play(box.animate.shift(2 * DOWN + 2 * LEFT), run_time=2,)
    self.play(box.animate.shift(2 * UP + 1 * RIGHT), run_time=2,)

    self.wait()

But this doesn't seem to work as I listed out. I'm facing difficulty in transforming the square into a circle at a random location (not origin!) along with the dot still remaining at the center.

Can anyone please help me out with this?!


Solution

  • I can think of this solutions to your problem:

    Define the circle at the coordinate where your square will end up: you can do this by adding .set_x(2.0).set_y(3.0) to the end of your definition of cr, so: cr = Circle(radius=0.5, color=GREEN, fill_opacity=0.5).set_x(2.0).set_y(3.0)

    You can also change the coordinates right before the transforming animation (in case in the future you choose the numbers randomly and don't know them beforehand) by adding the line cr.set_x(rand_1).set_y(rand_2), where rand_1 and rand_2 would be the numbers you have moved your square to.