Repository: ManimCommunity/manim
File: manim/mobject/opengl/opengl_vectorized_mobject.py (Python)

Code before:
    def get_end_anchors(self) -> np.ndarray:
        """Return the starting anchors of the bezier curves.

        Returns
        -------
        np.ndarray
            Starting anchors
        """
        nppc = self.n_points_per_curve
        return self.points[nppc - 1 :: nppc]

    def get_anchors(self) -> Iterable[np.ndarray]:
        """Returns the anchors of the curves forming the OpenGLVMobject.

        Returns
        -------
        Iterable[np.ndarray]
            The anchors.
        """
        points = self.points
        if len(points) == 1:
            return points

        s = self.get_start_anchors()
        e = self.get_end_anchors()
        return [s[i // 2] if i % 2 == 0 else e[i // 2] for i in range(len(s) + len(e))]

    def get_points_without_null_curves(self, atol=1e-9):
        nppc = self.n_points_per_curve
        points = self.points
        distinct_curves = reduce(
            op.or_,
            [
                (abs(points[i::nppc] - points[0::nppc]) > atol).any(1)
                for i in range(1, nppc)
            ],
        )
        return points[distinct_curves.repeat(nppc)]

    def get_arc_length(self, sample_points_per_curve: int | None = None) -> float:
        """Return the approximated length of the whole curve.

        Parameters
        ----------
        sample_points_per_curve
            Number of sample points per curve used to approximate the length. More points result in a better approximation.

        Returns
        -------
        float
            The length of the :class:`OpenGLVMobject`.

Review comment (suggestion):
Same comment as below, I'd prefer to stick with itertools:

```suggestion
        return list(it.chain.from_iterable(zip(s, t)))
```

Code after:
        return [points[i::nppc] for i in range(nppc)]

    def get_start_anchors(self) -> np.ndarray:
        """Returns the start anchors of the bezier curves.

        Returns
        -------
        np.ndarray
            Starting anchors
        """
        return self.points[0 :: self.n_points_per_curve]

    def get_end_anchors(self) -> np.ndarray:
        """Return the starting anchors of the bezier curves.

        Returns
        -------
        np.ndarray
            Starting anchors
        """
        nppc = self.n_points_per_curve
        return self.points[nppc - 1 :: nppc]

    def get_anchors(self) -> Iterable[np.ndarray]:
        """Returns the anchors of the curves forming the OpenGLVMobject.

        Returns
        -------
        Iterable[np.ndarray]
            The anchors.
        """
        points = self.points
        if len(points) == 1:
            return points

        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
        points = self.points
        distinct_curves = reduce(
            op.or_,
            [
                (abs(points[i::nppc] - points[0::nppc]) > atol).any(1)
                for i in range(1, nppc)
            ],
        )
        return points[distinct_curves.repeat(nppc)]