Repository: ManimCommunity/manim
File: manim/mobject/three_d/three_dimensions.py (Python)

Code before:

    Examples
    --------
    .. manim:: ExampleCone
        :save_last_frame:

        class ExampleCone(ThreeDScene):
            def construct(self):
                axes = ThreeDAxes()
                cone = Cone(direction=X_AXIS+Y_AXIS+2*Z_AXIS, resolution=8)
                self.set_camera_orientation(phi=5*PI/11, theta=PI/9)
                self.add(axes, cone)
    """

    def __init__(
        self,
        base_radius: float = 1,
        height: float = 1,
        direction: np.ndarray = Z_AXIS,
        show_base: bool = False,
        v_range: Sequence[float] = [0, TAU],
        u_min: float = 0,
        checkerboard_colors: Sequence[ParsableManimColor] | Literal[False] = False,
        **kwargs: Any,
    ) -> None:
        self.direction = direction
        self.theta = PI - np.arctan(base_radius / height)

        super().__init__(
            self.func,
            v_range=v_range,
            u_range=[u_min, np.sqrt(base_radius**2 + height**2)],
            checkerboard_colors=checkerboard_colors,
            **kwargs,
        )
        # used for rotations
        self.new_height = height
        self._current_theta = 0
        self._current_phi = 0
        self.base_circle = Circle(
            radius=base_radius,
            color=self.fill_color,
            fill_opacity=self.fill_opacity,
            stroke_width=0,
        )
        self.base_circle.shift(height * IN)
        self._set_start_and_end_attributes(direction)
        if show_base:
            self.add(self.base_circle)

        self._rotate_to_direction()

Review comment (bug):
This makes sure that the direction is copied and not referenced. References have caused some bugs in Manim:
```suggestion
        self.direction = np.array(direction)
```

Code after:
    Examples
    --------
    .. manim:: ExampleCone
        :save_last_frame:

        class ExampleCone(ThreeDScene):
            def construct(self):
                axes = ThreeDAxes()
                cone = Cone(direction=X_AXIS+Y_AXIS+2*Z_AXIS, resolution=8)
                self.set_camera_orientation(phi=5*PI/11, theta=PI/9)
                self.add(axes, cone)
    """

    def __init__(
        self,
        base_radius: float = 1,
        height: float = 1,
        direction: Vector3DLike = Z_AXIS,
        show_base: bool = False,
        v_range: tuple[float, float] = (0, TAU),
        u_min: float = 0,
        checkerboard_colors: Iterable[ParsableManimColor] | Literal[False] = False,
        **kwargs: Any,
    ) -> None:
        self.direction = np.array(direction)
        self.theta = PI - np.arctan(base_radius / height)

        super().__init__(
            self.func,
            v_range=v_range,
            u_range=(u_min, np.sqrt(base_radius**2 + height**2)),
            checkerboard_colors=checkerboard_colors,
            **kwargs,
        )
        # used for rotations
        self.new_height = height
        self._current_theta = 0
        self._current_phi = 0
        self.base_circle = Circle(
            radius=base_radius,
            color=self.fill_color,
            fill_opacity=self.fill_opacity,
            stroke_width=0,
        )
        self.base_circle.shift(height * IN)
        self._set_start_and_end_attributes(direction)
        if show_base:
            self.add(self.base_circle)

        self._rotate_to_direction()