Repository: ManimCommunity/manim

Issue:
`SpiralIn` is not working with the first Element
`SpiralIn` doesn't show the first Element sometimes, for examples just visit the current documentation of `SpiralIn`

- [ ] Tests are needed for SpiralIn to prevent this from happening again
- [ ] Implementation needs to be fixed


Discussion:
Started looking into this issue. Here is an example that fails to show the test object when I run `manim -pqh test.py`:

```python
class SpiralInBugExample(Scene):
    def construct(self):
        test = MathTex(r"\pi").scale(5)
        # test = Tex('test').scale(5) # Uncomment to test Tex
        # test = SingleStringMathTex(tex_string='test').scale(5) # Uncomment to test SingleStringMathTex
        # test = Circle() # Uncomment to test Circle
        shapes = VGroup(test)
        self.play(SpiralIn(shapes))
```
In the above example, you can uncomment any of the test lines to see the behavior of that object. They all behave the same. 

Something interesting I found was the issue occurs or goes away depending on whether or not you run another play before running SpiralIn. Here are the following orders with their results after running `manim -pqh test.py`. To see these results, replace the last line in my first example with one of these groups.
```python
self.play(SpiralIn(shapes)) # Will not show
self.play(DrawBorderThenFill(shapes)) # Will not show
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
```
```python
self.play(SpiralIn(shapes)) # Will not show
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
self.play(DrawBorderThenFill(shapes)) # Will show
```
```python
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
self.play(DrawBorderThenFill(shapes)) # Will show
self.play(SpiralIn(shapes)) # Will show
```
```python
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
self.play(SpiralIn(shapes)) # Will show
self.play(DrawBorderThenFill(shapes)) # Will show
```
```python
self.play(DrawBorderThenFill(shapes)) # Will show
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
self.play(SpiralIn(shapes)) # Will show
```
```python
self.play(DrawBorderThenFill(shapes)) # Will show
self.play(SpiralIn(shapes)) # Will not show
self.play(ShowSubmobjectsOneByOne(shapes)) # Will show
```
Each of the above groups behaved the same for each object type I tested. Another note, if SpiralIn isn't the first play, the SpiralIn play will cause the object to just fade in. It will not spiral. I don't know if this is expected. 

Going to continue looking into this the bug.

Resolving patch:
diff --git a/manim/animation/creation.py b/manim/animation/creation.py
--- a/manim/animation/creation.py
+++ b/manim/animation/creation.py
@@ -456,7 +456,7 @@ def __init__(
         fade_in_fraction=0.3,
         **kwargs,
     ) -> None:
-        self.shapes = shapes
+        self.shapes = shapes.copy()
         self.scale_factor = scale_factor
         self.shape_center = shapes.get_center()
         self.fade_in_fraction = fade_in_fraction
@@ -473,15 +473,21 @@ def __init__(
 
     def interpolate_mobject(self, alpha: float) -> None:
         alpha = self.rate_func(alpha)
-        for shape in self.shapes:
+        for original_shape, shape in zip(self.shapes, self.mobject):
             shape.restore()
-            shape.save_state()
-            opacity = shape.get_fill_opacity()
-            new_opacity = min(opacity, alpha * opacity / self.fade_in_fraction)
+            fill_opacity = original_shape.get_fill_opacity()
+            stroke_opacity = original_shape.get_stroke_opacity()
+            new_fill_opacity = min(
+                fill_opacity, alpha * fill_opacity / self.fade_in_fraction
+            )
+            new_stroke_opacity = min(
+                stroke_opacity, alpha * stroke_opacity / self.fade_in_fraction
+            )
             shape.shift((shape.final_position - shape.initial_position) * alpha)
             shape.rotate(TAU * alpha, about_point=self.shape_center)
             shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass())
-            shape.set_opacity(new_opacity)
+            shape.set_fill(opacity=new_fill_opacity)
+            shape.set_stroke(opacity=new_stroke_opacity)
 
 
 class ShowIncreasingSubsets(Animation):


Test patch:
diff --git a/tests/test_graphical_units/control_data/creation/SpiralIn.npz b/tests/test_graphical_units/control_data/creation/SpiralIn.npz
new file mode 100644
Binary files /dev/null and b/tests/test_graphical_units/control_data/creation/SpiralIn.npz differ
diff --git a/tests/test_graphical_units/test_creation.py b/tests/test_graphical_units/test_creation.py
--- a/tests/test_graphical_units/test_creation.py
+++ b/tests/test_graphical_units/test_creation.py
@@ -94,3 +94,11 @@ def test_z_index_introducer(scene):
     b.set_z_index(-1)
     scene.play(Create(b))
     scene.wait()
+
+
+@frames_comparison(last_frame=False)
+def test_SpiralIn(scene):
+    circle = Circle().shift(LEFT)
+    square = Square().shift(UP)
+    shapes = VGroup(circle, square)
+    scene.play(SpiralIn(shapes))