Repository: ManimCommunity/manim
File: manim/scene/three_d_scene.py (Python)

Code before:
                }
                x: ValueTracker = trackers[about]
                x.clear_updaters()
                self.remove(x)
            else:
                self.camera.clear_updaters()
        except:
            raise ValueError("Invalid ambient rotation angle.")

    def begin_3dillusion_camera_rotation(
        self,
        rate: Optional[float] = 1,
        origin_phi: Optional[float] = None,
        origin_theta: Optional[float] = None,
    ):
        """
        This method creates a 3D camera rotation illusion around the current camera orientation.

        Parameters
        ----------
        rate : int or float, optional
            The rate at which the camera rotation illusion should operate.
        origin_phi : int or float, optional
            The polar angle the camera should move around. Defaults to the current phi angle.
        origin_theta : int or float, optional
            The azimutal angle the camera should move around. Defaults to the current theta angle.
        """
        if origin_theta is None:
            origin_theta = self.renderer.camera.theta_tracker.get_value()
        if origin_phi is None:
            origin_phi = self.renderer.camera.phi_tracker.get_value()

        val_tracker_theta = ValueTracker(0)

        def update_theta(m, dt):
            val_tracker_theta.increment_value(dt * rate)
            val_for_left_right = 0.2 * np.sin(val_tracker_theta.get_value())
            return m.set_value(origin_theta + val_for_left_right)

        self.renderer.camera.theta_tracker.add_updater(update_theta)
        self.add(self.renderer.camera.theta_tracker)

        val_tracker_phi = ValueTracker(0)

        def update_phi(m, dt):
            val_tracker_phi.increment_value(dt * rate)
            val_for_up_down = 0.1 * np.cos(val_tracker_phi.get_value()) - 0.1
            return m.set_value(origin_phi + val_for_up_down)

        self.renderer.camera.phi_tracker.add_updater(update_phi)
        self.add(self.renderer.camera.phi_tracker)

Review comment (bug):
Thanks for adding documentation! Two minor issues:

- Specifying type hints in the method header makes these type hints here superfluous, I'll remove them,
- and some of the lines are a bit long, I've broken them.

```suggestion
        rate
            The rate at which the camera rotation illusion should operate.
        origin_phi
            The polar angle the camera should move around. Defaults
            to the current phi angle.
        origin_theta
            The azimutal angle the camera should move around. Defaults
            to the current theta angle.
```

Code after:
                }
                x: ValueTracker = trackers[about]
                x.clear_updaters()
                self.remove(x)
            else:
                self.camera.clear_updaters()
        except:
            raise ValueError("Invalid ambient rotation angle.")

    def begin_3dillusion_camera_rotation(
        self,
        rate: float = 1,
        origin_phi: Optional[float] = None,
        origin_theta: Optional[float] = None,
    ):
        """
        This method creates a 3D camera rotation illusion around
        the current camera orientation.

        Parameters
        ----------
        rate
            The rate at which the camera rotation illusion should operate.
        origin_phi
            The polar angle the camera should move around. Defaults
            to the current phi angle.
        origin_theta
            The azimutal angle the camera should move around. Defaults
            to the current theta angle.
        """
        if origin_theta is None:
            origin_theta = self.renderer.camera.theta_tracker.get_value()
        if origin_phi is None:
            origin_phi = self.renderer.camera.phi_tracker.get_value()

        val_tracker_theta = ValueTracker(0)

        def update_theta(m, dt):
            val_tracker_theta.increment_value(dt * rate)
            val_for_left_right = 0.2 * np.sin(val_tracker_theta.get_value())
            return m.set_value(origin_theta + val_for_left_right)

        self.renderer.camera.theta_tracker.add_updater(update_theta)
        self.add(self.renderer.camera.theta_tracker)

        val_tracker_phi = ValueTracker(0)

        def update_phi(m, dt):
            val_tracker_phi.increment_value(dt * rate)
            val_for_up_down = 0.1 * np.cos(val_tracker_phi.get_value()) - 0.1
            return m.set_value(origin_phi + val_for_up_down)