--- name: 3d description: ThreeDScene, 3D objects, surfaces, and 3D camera metadata: tags: 3d, threedscene, surface, sphere, cube, camera --- # 3D Graphics in Manim Create 3D visualizations with ThreeDScene. ## ThreeDScene Basics ```python from manim import * class Basic3D(ThreeDScene): def construct(self): # Set camera angle self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES) # Add 3D axes axes = ThreeDAxes() self.add(axes) ``` ## Camera Orientation ```python class CameraOrientation(ThreeDScene): def construct(self): axes = ThreeDAxes() # phi: angle from z-axis (0 = top view, 90 = side view) # theta: rotation around z-axis # gamma: roll angle self.set_camera_orientation( phi=75 * DEGREES, theta=-45 * DEGREES, gamma=0 ) self.add(axes) ``` ### Animated Camera Movement ```python class AnimatedCamera(ThreeDScene): def construct(self): axes = ThreeDAxes() self.add(axes) self.set_camera_orientation(phi=75*DEGREES, theta=0) # Animate camera movement self.move_camera(phi=45*DEGREES, theta=90*DEGREES, run_time=3) ``` ### Continuous Camera Rotation ```python class RotatingCamera(ThreeDScene): def construct(self): axes = ThreeDAxes() self.add(axes) self.set_camera_orientation(phi=75*DEGREES, theta=0) # Start ambient rotation self.begin_ambient_camera_rotation(rate=0.2) self.wait(5) self.stop_ambient_camera_rotation() ``` ## 3D Primitives ### Sphere ```python class SphereExample(ThreeDScene): def construct(self): sphere = Sphere(radius=1, resolution=(20, 20)) sphere.set_color(BLUE) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(sphere) ``` ### Cube / Prism ```python class CubeExample(ThreeDScene): def construct(self): cube = Cube(side_length=2, fill_opacity=0.8) cube.set_color(RED) # Rectangular prism prism = Prism(dimensions=[3, 1, 2]) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(cube) ``` ### Cylinder / Cone ```python class CylinderCone(ThreeDScene): def construct(self): cylinder = Cylinder(radius=1, height=2, fill_opacity=0.8) cone = Cone(base_radius=1, height=2, fill_opacity=0.8) cylinder.shift(LEFT * 2) cone.shift(RIGHT * 2) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(cylinder, cone) ``` ### Torus ```python class TorusExample(ThreeDScene): def construct(self): torus = Torus(major_radius=2, minor_radius=0.5) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(torus) ``` ## 3D Axes ```python class ThreeDAxesExample(ThreeDScene): def construct(self): axes = ThreeDAxes( x_range=[-4, 4, 1], y_range=[-4, 4, 1], z_range=[-4, 4, 1], x_length=8, y_length=8, z_length=6, ) # Add axis labels x_label = axes.get_x_axis_label("x") y_label = axes.get_y_axis_label("y") z_label = axes.get_z_axis_label("z") self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(axes, x_label, y_label, z_label) ``` ## Surface Plots ```python class SurfacePlot(ThreeDScene): def construct(self): axes = ThreeDAxes(x_range=[-3, 3], y_range=[-3, 3], z_range=[-2, 2]) # Function z = f(x, y) surface = axes.plot_surface( lambda u, v: np.sin(u) * np.cos(v), u_range=[-3, 3], v_range=[-3, 3], resolution=(30, 30), colorscale=[BLUE, GREEN, YELLOW, RED], ) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(axes, surface) ``` ### Surface Class (standalone) ```python class SurfaceExample(ThreeDScene): def construct(self): def param_func(u, v): x = u y = v z = np.sin(np.sqrt(u**2 + v**2)) return np.array([x, y, z]) surface = Surface( param_func, u_range=[-3, 3], v_range=[-3, 3], resolution=(30, 30), fill_opacity=0.8, ) surface.set_color_by_gradient(BLUE, GREEN) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(surface) ``` ## 3D Parametric Curves ```python class ParametricCurve3D(ThreeDScene): def construct(self): # Helix curve = ParametricFunction( lambda t: np.array([ np.cos(t), np.sin(t), t * 0.2 ]), t_range=[-4*PI, 4*PI], color=YELLOW ) curve.set_shade_in_3d(True) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(ThreeDAxes(), curve) ``` ## Shading in 3D ```python class Shading3D(ThreeDScene): def construct(self): sphere = Sphere() # Enable shading for realistic lighting sphere.set_shade_in_3d(True) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(sphere) ``` ## Arrow3D and Line3D ```python class Vectors3D(ThreeDScene): def construct(self): axes = ThreeDAxes() arrow = Arrow3D(ORIGIN, [2, 1, 2], color=RED) line = Line3D(ORIGIN, [-2, 1, 1], color=BLUE) self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) self.add(axes, arrow, line) ``` ## Best Practices 1. **Always set camera orientation** - Default view may not show 3D well 2. **Use set_shade_in_3d for realism** - Adds depth perception 3. **Use ambient camera rotation sparingly** - Can be disorienting 4. **Match resolution to detail needed** - Higher res = slower render 5. **Use colorscale for surfaces** - Shows elevation/value changes