MANIM: 3blue1brown style animations

This was fun: I had chatgpt codepilot write the code for me!
All I had to do was tell it what I wanted and iterate…

from manim import *
from manim import config

config.pixel_width  = 640
config.pixel_height = 360
config.frame_rate   =  30

class RotatingAxesVisualization(ThreeDScene):
    def construct(self):
        # Set up the fixed red axes
        fixed_axes = ThreeDAxes(
            x_range=(-2.5, 2.5, 1), y_range=(-2.5, 2.5, 1), z_range=(-1, 1, 0.5)
        ).set_color(RED).set_opacity(0.5)

        # Set up the rotating blue axes with specified ranges
        rotating_axes = ThreeDAxes(
            x_range=(-2.5, 2.5, 1), y_range=(-2.5, 2.5, 1), z_range=(-1, 1, 0.5)
        ).set_color(BLUE)

        # Camera configuration
        self.set_camera_orientation(phi=PI / 4, theta=PI / 6, zoom=1)

        # Add labels for the red axes (e_1, e_2, e_3)
        #e1_label = MathTex("e_1").next_to(fixed_axes.x_axis.get_end(), RIGHT)
        #e2_label = MathTex("e_2").next_to(fixed_axes.y_axis.get_end(), RIGHT)
        #e3_label = MathTex("e_3").next_to(fixed_axes.z_axis.get_end(), OUT)

        # Add labels for the blue axes (s_1, s_2, s_3)
        #s1_label = MathTex("s_1").next_to(rotating_axes.x_axis.get_end(), RIGHT)
        #s2_label = MathTex("s_2").next_to(rotating_axes.y_axis.get_end(), RIGHT)
        #s3_label = MathTex("s_3").next_to(rotating_axes.z_axis.get_end(), OUT)

        # Shade the blue plane (initial xy-plane of the blue axes)
        blue_plane = Polygon(
            [3.5, 3.5, 0], [-3.5, 3.5, 0], [-3.5, -3.5, 0], [3.5, -3.5, 0],
            fill_opacity=0.2, fill_color=BLUE, color=BLUE
        )

        # Add fixed axes, rotating axes, and blue plane to the scene
        self.add(fixed_axes) #, e1_label, e2_label, e3_label)
        self.add(rotating_axes, blue_plane )#, s1_label, s2_label, s3_label)

        # Define the target direction for the original z-axis
        target_direction = np.array([-3, -10, 20])
        target_direction = target_direction.astype(float)  # Ensure float dtype
        target_direction /= np.linalg.norm(target_direction)  # Normalize the direction

        # Rotation matrix to align the z-axis with the target direction
        rotation_axis = np.cross([0, 0, 1], target_direction)  # Axis of rotation
        rotation_angle = np.arccos(np.dot([0, 0, 1], target_direction))  # Angle of rotation

        # Animate the rotation of the blue axes and plane
        self.play(
            Rotate(rotating_axes, angle=rotation_angle, axis=rotation_axis, about_point=ORIGIN),
            Rotate(blue_plane, angle=rotation_angle, axis=rotation_axis, about_point=ORIGIN),
            run_time=3
        )

        # Add the blue vector along the blue x-axis after the rotation
        blue_vector = Arrow(start=ORIGIN, end=[2.1, 0, 0], buff=0, color=BLUE)
        blue_vector_label = MathTex(r"\mathbf{v}").next_to(blue_vector.get_end(), RIGHT)

        # Add blue vector independently to avoid unintended transformations
        self.add(blue_vector, blue_vector_label)

        # Rotate the blue vector within the blue plane by 60 degrees
        self.play(
            Rotate(blue_vector, angle=PI / 3, axis=[0, 0, 1], about_point=ORIGIN),
            Rotate(blue_vector_label, angle=PI / 3, axis=[0, 0, 1], about_point=ORIGIN),
            run_time=3
        )

        # Pause to display the final scene
        self.wait(2)

# Function to render the Manim scene into memory
def render_manim_scene(scene_class):
    with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as temp_file:
        output_path = temp_file.name
    config.media_dir = "."  # Keep media directory local
    config.output_file = output_path  # Output directly to the temp file
    scene_class().render()
    return output_path

# Render the scene
video_path = render_manim_scene(RotatingAxesVisualization)

# Create a Panel app to display the video
video_pane = pn.pane.Video(video_path, loop=False, autoplay=True, width=640, height=360)

# Build the Panel layout
layout = pn.Column(
    "# Visualization of a Rotation and Two Sets of Axes",
    "## This animation demonstrates a 3D rotation.",
    video_pane,
)

# Serve the Panel app
layout.servable()
2 Likes