Search code examples
pythonmanim

manim add dots to circle list


I am trying to create a bunch of circles around a bigger circle and the smaller circles need to have dots added to them. I am however struggling with adding the dots.

I believe it is because the object in the loop is a mobject and not a circle but I cannot figure out how to cast it, if this is indeed my issue.

Please help if you can

# manim scene.py PathExample
from manim import *

class PathExample(Scene):
    def construct(self):
        num_points = 16
        angles = [n * (360 / num_points) for n in range(num_points)]

        outer_circle = Circle(color=RED, radius=3)
        circles = [Circle(color=RED, radius=1).shift(4*LEFT).move_to(
        outer_circle.point_at_angle(n*DEGREES)) for n in angles]

        dots1 = []
        for c in circles:
            c.add_updater(lambda m: m.rotate(-0.01))
            dot = Dot(color=RED, radius=0, stroke_width=0).move_to(
                Circle(c).point_at_angle(0*DEGREES))
            dots1.append(dot)

        # # First attempt
        # dots1 = [Dot(color=RED, radius=0, stroke_width=0).move_to(
        #     c.point_at_angle(0*DEGREES)) for c in circles]

        rolling_outer_circle = VGroup(
            outer_circle, *circles)

        rolling_outer_circle.add_updater(lambda m: m.rotate(-0.01))
        self.add(rolling_outer_circle, outer_circle)
        self.play(rolling_outer_circle.animate, run_time=10, rate_func=linear)
        self.wait()

Executing manim scene1.py PathExample


Solution

  • I don't know why but main problem makes point_at_angle(0*DEGREES) - in some situations it gives wrong results.

    If I use n*DEGREES with for c, n in zip(circles, angles): then it works.

    Other problem is that Dot for radius=.1, stroke_width=0 is invisible so it needs ie. radius=.1


    Minimal working code

    from manim import *
    
    class PathExample(Scene):
    
        def construct(self):
            num_points = 16
            
            angles = [n * (360 / num_points) for n in range(num_points)]
    
            outer_circle = Circle(color=RED, radius=3)
            
            circles = [Circle(color=RED, radius=1).move_to(outer_circle.point_at_angle(n*DEGREES)) 
                        for n in angles]
    
            dots = []
            for c, n in zip(circles, angles):
                #c.add_updater(lambda m: m.rotate(-0.01))
                dot = Dot(color=RED, radius=.1, stroke_width=0).move_to(c.point_at_angle(n*DEGREES))
                dots.append(dot)
    
            # # First attempt
            #dots = [Dot(color=RED, radius=.1, stroke_width=0).move_to(c.point_at_angle(n*DEGREES)) 
            #            for c, n in zip(circles, angles)]
    
            rolling_outer_circle = VGroup(outer_circle, *circles, *dots)
    
            rolling_outer_circle.add_updater(lambda m: m.rotate(-0.01))
            
            self.add(rolling_outer_circle, outer_circle, *dots)
            self.play(rolling_outer_circle.animate, run_time=10, rate_func=linear)
            self.wait()
                    
    if __name__ == '__main__':
        import subprocess
        subprocess.run(['manim', '-p', '-ql', __file__, 'PathExample'])
    

    Result (partial animation):

    enter image description here