I am trying to make an animation where n points are equally distributed around a circle and an animation displays the permutations of those points by swapping their positions simultaeneously .
My issue is that when the animation ends either one of the points disappears from the scene or two distinct points get sent to the same position , here's the code :
from manim import*
import numpy as np
from itertools import*
import random
class CircleWithPoints(Scene):
def construct(self):
n = 6 # Number of points
radius = 2
colors = [RED, GREEN, GOLD, BLUE, PINK, PURPLE]
# Create circle
circle = Circle(radius=radius, color=WHITE)
self.play(Create(circle))
# Create points and assign colors
points = []
for i in range(n):
angle = i * 2 * np.pi / n
x = radius * np.cos(angle)
y = radius * np.sin(angle)
point = Dot(point=[x, y, 0], color=colors[i])
points.append(point)
self.play(Write((point)),run_animation=.25)
all_permutations = list(permutations(range(n)))
random_permutation =list(random.choice(all_permutations))
# Permutation animation
new_points=[]
animated_new_points=[]
animated_points=[]
for i in range(n):
next_index = random_permutation[i-1]
next_point = points[next_index-1]
if next_point is not points[i]:
animated_new_points.append(next_point)
animated_points.append(points[i])
self.wait(1)
self.play(*[Swap(animated_points[i],animated_new_points[i]) for i in range(len(animated_points))])
self.wait(1)
I tried making a copy of the list of points to only take into account the points that are not fixed by the permutation however it doesn't seem like it worked
It's either a bug or an incorrect usage of Swap
(which is only another name for CyclicReplace
). I didn't investigate it further, but here is a simple solution: Replace Swap
with Transform
.
self.play(*[Transform(animated_points[i],animated_new_points[i]) for i in range(len(animated_points))])
If you want to see how Swap
is intended to be used, you can do sth. like this:
...
points = VGroup()
for i in range(n):
angle = i * 2 * np.pi / n
x = radius * np.cos(angle)
y = radius * np.sin(angle)
point = Dot(point=[x, y, 0], color=colors[i])
points.add(point)
self.play(Write((point)),run_animation=.25)
...
self.play(Swap(*points))
...
Btw., when you are storing multiple VMobject
like Dot
I would recommend to use VGroup
, which makes working with these objects much easier than a general python list.