Repository: ManimCommunity/manim

Issue:
VMobject: get_anchors() and get_anchors_and_handles() different behavior
## Description of bug / unexpected behavior
It seems that get_anchors() returns a new object whereas get_anchors_and_handles() returns a reference. 
get_start_anchors() and get_end_anchors() also return a reference. 


## Expected behavior
Consistency between the methods would be desirable. 


## How to reproduce the issue

The following snippet produce

```py

c = Circle()

print("get_anchors = ", c.get_anchors()[-1])
print("get_anchors_and_handles = ", c.get_anchors_and_handles()[-1][-1])
c.get_anchors_and_handles()[-1][-1] += 2 * mn.RIGHT
print("get_anchors = ", c.get_anchors()[-1])
print("get_anchors_and_handles = ", c.get_anchors_and_handles()[-1][-1])
```
produces 

```
get_anchors =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors_and_handles =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors =  [ 3.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors_and_handles =  [ 3.0000000e+00 -2.4492936e-16  0.0000000e+00]
```

whereas the following snippet

```py

c =  Circle()

print("get_anchors = ", c.get_anchors()[-1])
print("get_anchors_and_handles = ", c.get_anchors_and_handles()[-1][-1])
c.get_anchors()[-1] += 2 * mn.RIGHT
print("get_anchors = ", c.get_anchors()[-1])
print("get_anchors_and_handles = ", c.get_anchors_and_handles()[-1][-1])
```

produces

```
get_anchors =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors_and_handles =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
get_anchors_and_handles =  [ 1.0000000e+00 -2.4492936e-16  0.0000000e+00]
```



Discussion:

Resolving patch:
diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py
--- a/manim/mobject/mobject.py
+++ b/manim/mobject/mobject.py
@@ -2836,7 +2836,8 @@ def construct(self):
             >>> result = rect.copy().become(circ, stretch=True)
             >>> result.height, result.width
             (2.0, 4.0)
-            >>> ellipse_eq = np.sum(result.get_anchors()**2 * [1/4, 1, 0], axis=1)
+            >>> ellipse_points = np.array(result.get_anchors())
+            >>> ellipse_eq = np.sum(ellipse_points**2 * [1/4, 1, 0], axis=1)
             >>> np.allclose(ellipse_eq, 1)
             True
 
@@ -2849,13 +2850,15 @@ def construct(self):
             >>> result = rect.copy().become(circ, match_height=True)
             >>> result.height, result.width
             (2.0, 2.0)
-            >>> circle_eq = np.sum(result.get_anchors()**2, axis=1)
+            >>> circle_points = np.array(result.get_anchors())
+            >>> circle_eq = np.sum(circle_points**2, axis=1)
             >>> np.allclose(circle_eq, 1)
             True
             >>> result = rect.copy().become(circ, match_width=True)
             >>> result.height, result.width
             (4.0, 4.0)
-            >>> circle_eq = np.sum(result.get_anchors()**2, axis=1)
+            >>> circle_points = np.array(result.get_anchors())
+            >>> circle_eq = np.sum(circle_points**2, axis=1)
             >>> np.allclose(circle_eq, 2**2)
             True
 
diff --git a/manim/mobject/opengl/opengl_vectorized_mobject.py b/manim/mobject/opengl/opengl_vectorized_mobject.py
--- a/manim/mobject/opengl/opengl_vectorized_mobject.py
+++ b/manim/mobject/opengl/opengl_vectorized_mobject.py
@@ -1025,7 +1025,7 @@ def proportion_from_point(
 
         return alpha
 
-    def get_anchors_and_handles(self):
+    def get_anchors_and_handles(self) -> Iterable[np.ndarray]:
         """
         Returns anchors1, handles, anchors2,
         where (anchors1[i], handles[i], anchors2[i])
@@ -1057,27 +1057,21 @@ def get_end_anchors(self) -> np.ndarray:
         nppc = self.n_points_per_curve
         return self.points[nppc - 1 :: nppc]
 
-    def get_anchors(self) -> np.ndarray:
+    def get_anchors(self) -> Iterable[np.ndarray]:
         """Returns the anchors of the curves forming the OpenGLVMobject.
 
         Returns
         -------
-        np.ndarray
+        Iterable[np.ndarray]
             The anchors.
         """
         points = self.points
         if len(points) == 1:
             return points
-        return np.array(
-            list(
-                it.chain(
-                    *zip(
-                        self.get_start_anchors(),
-                        self.get_end_anchors(),
-                    )
-                ),
-            ),
-        )
+
+        s = self.get_start_anchors()
+        e = self.get_end_anchors()
+        return list(it.chain.from_iterable(zip(s, e)))
 
     def get_points_without_null_curves(self, atol=1e-9):
         nppc = self.n_points_per_curve
diff --git a/manim/mobject/types/vectorized_mobject.py b/manim/mobject/types/vectorized_mobject.py
--- a/manim/mobject/types/vectorized_mobject.py
+++ b/manim/mobject/types/vectorized_mobject.py
@@ -1553,9 +1553,10 @@ def get_anchors(self) -> Point3D_Array:
         """
         if self.points.shape[0] == 1:
             return self.points
-        return np.array(
-            tuple(it.chain(*zip(self.get_start_anchors(), self.get_end_anchors()))),
-        )
+
+        s = self.get_start_anchors()
+        e = self.get_end_anchors()
+        return list(it.chain.from_iterable(zip(s, e)))
 
     def get_points_defining_boundary(self) -> Point3D_Array:
         # Probably returns all anchors, but this is weird regarding  the name of the method.


Test patch: