Animation engine for explanatory math videos with programmatic mathematical visualization capabilities
—
ManimGL provides comprehensive 3D object support including parametric surfaces, geometric solids, and specialized 3D mathematical constructs. These objects integrate with the 3D camera system for creating immersive mathematical visualizations with depth and perspective.
Foundation class for all 3D surface objects with lighting and shading support.
class Surface(VMobject):
def __init__(self, func=None, **kwargs):
"""
Base class for 3D surfaces.
Parameters:
- func: callable, surface function (u, v) -> (x, y, z)
- u_range: tuple, (u_min, u_max) parameter range
- v_range: tuple, (v_min, v_max) parameter range
- resolution: tuple, (u_res, v_res) surface resolution
- surface_piece_config: dict, styling for surface pieces
- fill_color: surface interior color
- fill_opacity: float, surface opacity (0-1)
- checkerboard_colors: list, alternating surface colors
- stroke_color: surface outline color
- stroke_width: float, outline thickness
- should_make_jagged: bool, add surface roughness
- pre_function_handle_to_anchor_scale_factor: float, scaling factor
"""
def set_fill_by_checkerboard(self, *colors, opacity=None):
"""
Set checkerboard pattern fill.
Parameters:
- colors: Color arguments for checkerboard pattern
- opacity: float, pattern opacity
Returns:
Surface (self)
"""
def set_fill_by_value(self, axes, func, **kwargs):
"""
Set fill color based on function values.
Parameters:
- axes: Axes object for coordinate reference
- func: callable, function for color mapping (x, y, z) -> float
- colorscale: str, color scale name ('viridis', 'plasma', etc.)
- alpha: float, opacity
Returns:
Surface (self)
"""
class ParametricSurface(Surface):
def __init__(self, func, u_range=(0, 1), v_range=(0, 1), **kwargs):
"""
Parametric surface defined by r(u, v) = (x(u,v), y(u,v), z(u,v)).
Parameters:
- func: callable, parametric function (u, v) -> (x, y, z)
- u_range: tuple, u parameter range
- v_range: tuple, v parameter range
- checkerboard_colors: list, alternating colors for surface patches
- resolution: tuple, (u_resolution, v_resolution)
"""
def get_point_from_function(self, u, v):
"""
Get 3D point at parameter values (u, v).
Parameters:
- u: float, u parameter value
- v: float, v parameter value
Returns:
np.array, 3D point on surface
"""
class TexturedSurface(Surface):
def __init__(self, surface, image_file, **kwargs):
"""
Surface with image texture mapping.
Parameters:
- surface: Surface object to apply texture to
- image_file: str, path to texture image file
- alpha: float, texture opacity
"""Standard 3D geometric shapes and solids.
class Sphere(ParametricSurface):
def __init__(self, radius=1, **kwargs):
"""
3D sphere surface.
Parameters:
- radius: float, sphere radius
- u_range: tuple, latitude parameter range (default: (0, TAU))
- v_range: tuple, longitude parameter range (default: (0, PI))
- resolution: tuple, surface resolution
"""
class Cube(VGroup):
def __init__(self, side_length=2, **kwargs):
"""
3D cube made of square faces.
Parameters:
- side_length: float, edge length
- fill_opacity: float, face opacity
- stroke_color: edge color
- stroke_width: float, edge thickness
"""
def get_face_by_index(self, index):
"""
Get cube face by index.
Parameters:
- index: int, face index (0-5)
Returns:
Square, cube face
"""
class Prism(Cube):
def __init__(self, dimensions=(3, 2, 1), **kwargs):
"""
Rectangular prism/cuboid.
Parameters:
- dimensions: tuple, (width, height, depth)
"""
class Cone(ParametricSurface):
def __init__(self, height=2, base_radius=1, **kwargs):
"""
3D cone surface.
Parameters:
- height: float, cone height
- base_radius: float, base circle radius
- u_range: tuple, radial parameter range
- v_range: tuple, height parameter range
"""
class Cylinder(ParametricSurface):
def __init__(self, height=2, radius=1, **kwargs):
"""
3D cylinder surface.
Parameters:
- height: float, cylinder height
- radius: float, cylinder radius
- u_range: tuple, angular parameter range (default: (0, TAU))
- v_range: tuple, height parameter range
"""
class Torus(ParametricSurface):
def __init__(self, major_radius=3, minor_radius=1, **kwargs):
"""
3D torus (donut shape).
Parameters:
- major_radius: float, distance from center to tube center
- minor_radius: float, tube radius
- u_range: tuple, major circle parameter range
- v_range: tuple, minor circle parameter range
"""Specialized surfaces for mathematical visualization and education.
class SurfaceFromFunction(ParametricSurface):
def __init__(self, function, x_range=(-3, 3), y_range=(-3, 3), **kwargs):
"""
Surface defined by z = f(x, y).
Parameters:
- function: callable, height function f(x, y) -> z
- x_range: tuple, x domain
- y_range: tuple, y domain
- resolution: tuple, sampling resolution
"""
class Paraboloid(SurfaceFromFunction):
def __init__(self, **kwargs):
"""
Paraboloid surface z = x² + y².
Parameters:
- x_range: tuple, x domain
- y_range: tuple, y domain
"""
class Hyperboloid(ParametricSurface):
def __init__(self, **kwargs):
"""
Hyperboloid of one sheet.
Parameters:
- u_range: tuple, first parameter range
- v_range: tuple, second parameter range
"""
class Klein_Bottle(ParametricSurface):
def __init__(self, **kwargs):
"""
Klein bottle surface (non-orientable).
Parameters:
- u_range: tuple, first parameter range
- v_range: tuple, second parameter range
"""
class Mobius_Strip(ParametricSurface):
def __init__(self, **kwargs):
"""
Möbius strip surface (non-orientable).
Parameters:
- u_range: tuple, length parameter range
- v_range: tuple, width parameter range
"""
class ParametricSurface3D(ParametricSurface):
def __init__(self, func, **kwargs):
"""
General 3D parametric surface with advanced options.
Parameters:
- func: callable, surface function (u, v) -> (x, y, z)
- normal_nudge: float, normal vector adjustment
- depth_test: bool, enable depth testing
- gloss: float, surface shininess (0-1)
- shadow: float, shadow intensity (0-1)
"""Three-dimensional curves and line objects.
class ParametricCurve3D(VMobject):
def __init__(self, func, t_range=(0, 1), **kwargs):
"""
3D parametric curve r(t) = (x(t), y(t), z(t)).
Parameters:
- func: callable, curve function t -> (x, y, z)
- t_range: tuple, parameter range
- dt: float, parameter sampling step
- stroke_width: float, curve thickness
- stroke_color: curve color
"""
class CurvesAsSubmobjects(VGroup):
def __init__(self, *curves, **kwargs):
"""
Group of 3D curves as submobjects.
Parameters:
- curves: ParametricCurve3D objects
"""
class Line3D(ParametricCurve3D):
def __init__(self, start, end, **kwargs):
"""
3D line segment.
Parameters:
- start: np.array, starting point in 3D
- end: np.array, ending point in 3D
"""
class Arrow3D(Line3D):
def __init__(self, start, end, **kwargs):
"""
3D arrow with 3D arrowhead.
Parameters:
- start: np.array, arrow start point
- end: np.array, arrow end point
- thickness: float, arrow shaft thickness
- height: float, arrowhead height
"""Collections of 3D objects and point-based representations.
class DotCloud(PMobject):
def __init__(self, *points, **kwargs):
"""
Cloud of 3D dots/points.
Parameters:
- points: np.array points or list of points in 3D space
- color: dot color
- radius: float, dot size
- density: int, dots per unit area
"""
def add_points(self, points):
"""
Add more points to the cloud.
Parameters:
- points: np.array, additional 3D points
Returns:
DotCloud (self)
"""
class Point3D(Dot):
def __init__(self, location=ORIGIN, **kwargs):
"""
Single 3D point with depth.
Parameters:
- location: np.array, 3D coordinates
- radius: float, point size
- color: point color
"""
class Dot3D(Point3D):
def __init__(self, point=ORIGIN, **kwargs):
"""
3D dot that maintains consistent size regardless of depth.
Parameters:
- point: np.array, 3D location
- radius: float, dot radius
- stroke_width: float, outline thickness
"""Text objects positioned in 3D space.
class Text3D(Text):
def __init__(self, text, **kwargs):
"""
3D text object with depth and perspective.
Parameters:
- text: str, text content
- depth: float, text extrusion depth
- font_size: float, text size
- perspective_factor: float, perspective scaling
"""
class Tex3D(Tex):
def __init__(self, *tex_strings, **kwargs):
"""
3D LaTeX mathematical expressions.
Parameters:
- tex_strings: str arguments, LaTeX content
- depth: float, extrusion depth
- shading: float, 3D shading intensity
"""from manimgl import *
class SurfaceExample(ThreeDScene):
def construct(self):
# Create parametric surface
surface = ParametricSurface(
lambda u, v: np.array([
u,
v,
0.5 * (u**2 + v**2)
]),
u_range=(-2, 2),
v_range=(-2, 2),
checkerboard_colors=[BLUE_D, BLUE_E],
resolution=(20, 20)
)
# Set camera angle
self.set_camera_orientation(phi=75*DEGREES, theta=45*DEGREES)
self.play(ShowCreation(surface))
self.begin_ambient_camera_rotation(rate=0.1)
self.wait(5)class SolidsExample(ThreeDScene):
def construct(self):
# Create various 3D solids
sphere = Sphere(radius=1, color=RED).shift(LEFT * 3)
cube = Cube(side_length=1.5, color=BLUE)
cone = Cone(height=2, base_radius=1, color=GREEN).shift(RIGHT * 3)
solids = VGroup(sphere, cube, cone)
self.set_camera_orientation(phi=60*DEGREES, theta=45*DEGREES)
self.play(ShowCreation(solids))
self.begin_ambient_camera_rotation(rate=0.05)
self.wait(3)class MathSurfaceExample(ThreeDScene):
def construct(self):
# Mathematical function surface
def wave_function(u, v):
return np.array([
u,
v,
np.sin(u) * np.cos(v)
])
surface = ParametricSurface(
wave_function,
u_range=(-PI, PI),
v_range=(-PI, PI),
resolution=(30, 30)
)
# Color by height
surface.set_fill_by_value(
axes=None,
func=lambda x, y, z: z,
colorscale="viridis"
)
self.set_camera_orientation(phi=70*DEGREES)
self.play(ShowCreation(surface))
self.wait()class Curve3DExample(ThreeDScene):
def construct(self):
# 3D parametric curve (helix)
helix = ParametricCurve3D(
lambda t: np.array([
np.cos(t),
np.sin(t),
0.3 * t
]),
t_range=(0, 4*PI),
stroke_width=4,
color=YELLOW
)
self.set_camera_orientation(phi=75*DEGREES, theta=45*DEGREES)
self.play(ShowCreation(helix), run_time=3)
self.begin_ambient_camera_rotation(rate=0.1)
self.wait(3)class Interactive3DExample(InteractiveScene, ThreeDScene):
def construct(self):
# Create surface that can be manipulated
surface = ParametricSurface(
lambda u, v: np.array([u, v, u*v]),
u_range=(-2, 2),
v_range=(-2, 2),
color=BLUE
)
self.add(surface)
self.set_camera_orientation(phi=60*DEGREES)
def on_key_press(self, symbol, modifiers):
if symbol == ord('r'):
# Rotate surface on 'r' key
self.play(Rotate(self.mobjects[0], PI/4, axis=UP))class TexturedExample(ThreeDScene):
def construct(self):
# Create sphere
sphere = Sphere(radius=2, resolution=(50, 50))
# Apply texture (requires image file)
# textured_sphere = TexturedSurface(sphere, "earth_texture.jpg")
self.set_camera_orientation(phi=60*DEGREES, theta=30*DEGREES)
self.play(ShowCreation(sphere))
self.begin_ambient_camera_rotation(rate=0.02)
self.wait(5)class PointCloudExample(ThreeDScene):
def construct(self):
# Generate random 3D points
points = [
np.array([
2 * (np.random.random() - 0.5),
2 * (np.random.random() - 0.5),
2 * (np.random.random() - 0.5)
])
for _ in range(1000)
]
cloud = DotCloud(*points, color=BLUE, radius=0.05)
self.set_camera_orientation(phi=75*DEGREES, theta=45*DEGREES)
self.play(ShowCreation(cloud))
self.begin_ambient_camera_rotation(rate=0.1)
self.wait(3)Install with Tessl CLI
npx tessl i tessl/pypi-manimgldocs