manim-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/demo.mp4 +0 -0
- package/dist/index.js +65 -0
- package/dist/mcp-app.html +142 -0
- package/dist/server.js +1492 -0
- package/package.json +67 -0
- package/references/composer/SKILL.md +154 -0
- package/references/composer/references/3b1b-series-patterns.md +217 -0
- package/references/composer/references/domain-planning-guides/calculus-planning.md +188 -0
- package/references/composer/references/domain-planning-guides/linear-algebra-planning.md +169 -0
- package/references/composer/references/domain-planning-guides/ml-planning.md +286 -0
- package/references/composer/references/domain-planning-guides/number-theory-planning.md +187 -0
- package/references/composer/references/domain-planning-guides/physics-planning.md +249 -0
- package/references/composer/references/domain-planning-guides/probability-planning.md +200 -0
- package/references/composer/references/mathematical-storytelling.md +359 -0
- package/references/composer/references/narrative-patterns.md +221 -0
- package/references/composer/references/opening-patterns.md +284 -0
- package/references/composer/references/pacing-guide.md +289 -0
- package/references/composer/references/scene-archetypes.md +534 -0
- package/references/composer/references/scene-examples.md +379 -0
- package/references/composer/references/visual-techniques.md +480 -0
- package/references/composer/templates/scenes-template.md +147 -0
- package/references/manimce/SKILL.md +166 -0
- package/references/manimce/examples/3d_visualization.py +373 -0
- package/references/manimce/examples/basic_animations.py +212 -0
- package/references/manimce/examples/graph_plotting.py +401 -0
- package/references/manimce/examples/lorenz_attractor.py +172 -0
- package/references/manimce/examples/math_visualization.py +315 -0
- package/references/manimce/examples/updater_patterns.py +369 -0
- package/references/manimce/rules/3b1b-translation.md +594 -0
- package/references/manimce/rules/3d.md +254 -0
- package/references/manimce/rules/advanced-animations.md +594 -0
- package/references/manimce/rules/animation-groups.md +212 -0
- package/references/manimce/rules/animations.md +128 -0
- package/references/manimce/rules/api-pitfalls.md +89 -0
- package/references/manimce/rules/axes.md +214 -0
- package/references/manimce/rules/camera.md +208 -0
- package/references/manimce/rules/cli.md +232 -0
- package/references/manimce/rules/color-conventions.md +444 -0
- package/references/manimce/rules/colors.md +199 -0
- package/references/manimce/rules/config.md +264 -0
- package/references/manimce/rules/creation-animations.md +158 -0
- package/references/manimce/rules/graphing.md +233 -0
- package/references/manimce/rules/grouping.md +220 -0
- package/references/manimce/rules/latex.md +202 -0
- package/references/manimce/rules/lines.md +241 -0
- package/references/manimce/rules/long-form-video.md +552 -0
- package/references/manimce/rules/mathematical-domains.md +689 -0
- package/references/manimce/rules/mobjects.md +116 -0
- package/references/manimce/rules/multi-scene-composition.md +112 -0
- package/references/manimce/rules/pedagogy.md +532 -0
- package/references/manimce/rules/physics-simulations.md +610 -0
- package/references/manimce/rules/positioning.md +211 -0
- package/references/manimce/rules/scenes.md +121 -0
- package/references/manimce/rules/shapes.md +300 -0
- package/references/manimce/rules/styling.md +177 -0
- package/references/manimce/rules/text-animations.md +222 -0
- package/references/manimce/rules/text.md +189 -0
- package/references/manimce/rules/timing.md +227 -0
- package/references/manimce/rules/transform-animations.md +157 -0
- package/references/manimce/rules/updaters.md +226 -0
- package/references/manimce/templates/basic_scene.py +64 -0
- package/references/manimce/templates/camera_scene.py +100 -0
- package/references/manimce/templates/threed_scene.py +138 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: manimce-best-practices
|
|
3
|
+
description: |
|
|
4
|
+
Trigger when: (1) User mentions "manim" or "Manim Community" or "ManimCE", (2) Code contains `from manim import *`, (3) User runs `manim` CLI commands, (4) Working with Scene, MathTex, Create(), or ManimCE-specific classes.
|
|
5
|
+
|
|
6
|
+
Best practices for Manim Community Edition - the community-maintained Python animation engine. Covers Scene structure, animations, LaTeX/MathTex, 3D with ThreeDScene, camera control, styling, and CLI usage.
|
|
7
|
+
|
|
8
|
+
NOT for ManimGL/3b1b version (which uses `manimlib` imports and `manimgl` CLI).
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## How to use
|
|
12
|
+
|
|
13
|
+
Read individual rule files for detailed explanations and code examples:
|
|
14
|
+
|
|
15
|
+
### Core Concepts
|
|
16
|
+
- [rules/scenes.md](rules/scenes.md) - Scene structure, construct method, and scene types
|
|
17
|
+
- [rules/mobjects.md](rules/mobjects.md) - Mobject types, VMobject, Groups, and positioning
|
|
18
|
+
- [rules/animations.md](rules/animations.md) - Animation classes, playing animations, and timing
|
|
19
|
+
|
|
20
|
+
### Creation & Transformation
|
|
21
|
+
- [rules/creation-animations.md](rules/creation-animations.md) - Create, Write, FadeIn, DrawBorderThenFill
|
|
22
|
+
- [rules/transform-animations.md](rules/transform-animations.md) - Transform, ReplacementTransform, morphing
|
|
23
|
+
- [rules/animation-groups.md](rules/animation-groups.md) - AnimationGroup, LaggedStart, Succession
|
|
24
|
+
|
|
25
|
+
### Text & Math
|
|
26
|
+
- [rules/text.md](rules/text.md) - Text mobjects, fonts, and styling
|
|
27
|
+
- [rules/latex.md](rules/latex.md) - MathTex, Tex, LaTeX rendering, and coloring formulas
|
|
28
|
+
- [rules/text-animations.md](rules/text-animations.md) - Write, AddTextLetterByLetter, TypeWithCursor
|
|
29
|
+
|
|
30
|
+
### Styling & Appearance
|
|
31
|
+
- [rules/colors.md](rules/colors.md) - Color constants, gradients, and color manipulation
|
|
32
|
+
- [rules/styling.md](rules/styling.md) - Fill, stroke, opacity, and visual properties
|
|
33
|
+
|
|
34
|
+
### Positioning & Layout
|
|
35
|
+
- [rules/positioning.md](rules/positioning.md) - move_to, next_to, align_to, shift methods
|
|
36
|
+
- [rules/grouping.md](rules/grouping.md) - VGroup, Group, arrange, and layout patterns
|
|
37
|
+
|
|
38
|
+
### Coordinate Systems & Graphing
|
|
39
|
+
- [rules/axes.md](rules/axes.md) - Axes, NumberPlane, coordinate systems
|
|
40
|
+
- [rules/graphing.md](rules/graphing.md) - Plotting functions, parametric curves
|
|
41
|
+
- [rules/3d.md](rules/3d.md) - ThreeDScene, 3D axes, surfaces, camera orientation
|
|
42
|
+
|
|
43
|
+
### Animation Control
|
|
44
|
+
- [rules/timing.md](rules/timing.md) - Rate functions, easing, run_time, lag_ratio
|
|
45
|
+
- [rules/updaters.md](rules/updaters.md) - Updaters, ValueTracker, dynamic animations
|
|
46
|
+
- [rules/camera.md](rules/camera.md) - MovingCameraScene, zoom, pan, frame manipulation
|
|
47
|
+
|
|
48
|
+
### Configuration & CLI
|
|
49
|
+
- [rules/cli.md](rules/cli.md) - Command-line interface, rendering options, quality flags
|
|
50
|
+
- [rules/config.md](rules/config.md) - Configuration system, manim.cfg, settings
|
|
51
|
+
|
|
52
|
+
### Shapes & Geometry
|
|
53
|
+
- [rules/shapes.md](rules/shapes.md) - Circle, Square, Rectangle, Polygon, and geometric primitives
|
|
54
|
+
- [rules/lines.md](rules/lines.md) - Line, Arrow, Vector, DashedLine, and connectors
|
|
55
|
+
|
|
56
|
+
### Long-Form Video Creation (3b1b Patterns)
|
|
57
|
+
- [rules/long-form-video.md](rules/long-form-video.md) - Scene-per-section architecture, narrative structure, pacing, transitions, opening quotes, end screens
|
|
58
|
+
- [rules/pedagogy.md](rules/pedagogy.md) - Pedagogical patterns: intuition first, controlled revelation, multiple perspectives, mystery-first hooks
|
|
59
|
+
- [rules/advanced-animations.md](rules/advanced-animations.md) - TransformMatchingTex, VShowPassingFlash, UpdateFromAlphaFunc, generate_target, always_redraw, cycle animations
|
|
60
|
+
|
|
61
|
+
### Mathematical Domains
|
|
62
|
+
- [rules/mathematical-domains.md](rules/mathematical-domains.md) - Domain-specific patterns for linear algebra, calculus, probability, complex analysis, number theory, topology, neural networks
|
|
63
|
+
- [rules/color-conventions.md](rules/color-conventions.md) - The complete 3b1b color system: domain colors, value_to_color, backstroke, HSL gradients
|
|
64
|
+
|
|
65
|
+
### Physics & Simulation
|
|
66
|
+
- [rules/physics-simulations.md](rules/physics-simulations.md) - Euler integration, pendulums, spring-mass systems, particle systems, phase space, vector fields, sound
|
|
67
|
+
|
|
68
|
+
### ManimGL Translation
|
|
69
|
+
- [rules/3b1b-translation.md](rules/3b1b-translation.md) - Translating 3b1b/ManimGL code to ManimCE: ShowCreation to Create, CONFIG to __init__, frame access, LaTeX classes
|
|
70
|
+
|
|
71
|
+
## Working Examples
|
|
72
|
+
|
|
73
|
+
Complete, tested example files demonstrating common patterns:
|
|
74
|
+
|
|
75
|
+
- [examples/basic_animations.py](examples/basic_animations.py) - Shape creation, text, lagged animations, path movement
|
|
76
|
+
- [examples/math_visualization.py](examples/math_visualization.py) - LaTeX equations, color-coded math, derivations
|
|
77
|
+
- [examples/updater_patterns.py](examples/updater_patterns.py) - ValueTracker, dynamic animations, physics simulations
|
|
78
|
+
- [examples/graph_plotting.py](examples/graph_plotting.py) - Axes, functions, areas, Riemann sums, polar plots
|
|
79
|
+
- [examples/3d_visualization.py](examples/3d_visualization.py) - ThreeDScene, surfaces, 3D camera, parametric curves
|
|
80
|
+
|
|
81
|
+
## Scene Templates
|
|
82
|
+
|
|
83
|
+
Copy and modify these templates to start new projects:
|
|
84
|
+
|
|
85
|
+
- [templates/basic_scene.py](templates/basic_scene.py) - Standard 2D scene template
|
|
86
|
+
- [templates/camera_scene.py](templates/camera_scene.py) - MovingCameraScene with zoom/pan
|
|
87
|
+
- [templates/threed_scene.py](templates/threed_scene.py) - 3D scene with surfaces and camera rotation
|
|
88
|
+
|
|
89
|
+
## Quick Reference
|
|
90
|
+
|
|
91
|
+
### Basic Scene Structure
|
|
92
|
+
```python
|
|
93
|
+
from manim import *
|
|
94
|
+
|
|
95
|
+
class MyScene(Scene):
|
|
96
|
+
def construct(self):
|
|
97
|
+
# Create mobjects
|
|
98
|
+
circle = Circle()
|
|
99
|
+
|
|
100
|
+
# Add to scene (static)
|
|
101
|
+
self.add(circle)
|
|
102
|
+
|
|
103
|
+
# Or animate
|
|
104
|
+
self.play(Create(circle))
|
|
105
|
+
|
|
106
|
+
# Wait
|
|
107
|
+
self.wait(1)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Render Command
|
|
111
|
+
```bash
|
|
112
|
+
# Basic render with preview
|
|
113
|
+
manim -pql scene.py MyScene
|
|
114
|
+
|
|
115
|
+
# Quality flags: -ql (low), -qm (medium), -qh (high), -qk (4k)
|
|
116
|
+
manim -pqh scene.py MyScene
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Key Differences from 3b1b/ManimGL
|
|
120
|
+
|
|
121
|
+
| Feature | Manim Community | 3b1b/ManimGL |
|
|
122
|
+
|---------|-----------------|--------------|
|
|
123
|
+
| Import | `from manim import *` | `from manimlib import *` |
|
|
124
|
+
| CLI | `manim` | `manimgl` |
|
|
125
|
+
| Math text | `MathTex(r"\pi")` | `Tex(R"\pi")` |
|
|
126
|
+
| Scene | `Scene` | `InteractiveScene` |
|
|
127
|
+
| Package | `manim` (PyPI) | `manimgl` (PyPI) |
|
|
128
|
+
|
|
129
|
+
### Jupyter Notebook Support
|
|
130
|
+
|
|
131
|
+
Use the `%%manim` cell magic:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
%%manim -qm MyScene
|
|
135
|
+
class MyScene(Scene):
|
|
136
|
+
def construct(self):
|
|
137
|
+
self.play(Create(Circle()))
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Common Pitfalls to Avoid
|
|
141
|
+
|
|
142
|
+
1. **Version confusion** - Ensure you're using `manim` (Community), not `manimgl` (3b1b version)
|
|
143
|
+
2. **Check imports** - `from manim import *` is ManimCE; `from manimlib import *` is ManimGL
|
|
144
|
+
3. **Outdated tutorials** - Video tutorials may be outdated; prefer official documentation
|
|
145
|
+
4. **manimpango issues** - If text rendering fails, check manimpango installation requirements
|
|
146
|
+
5. **PATH issues (Windows)** - If `manim` command not found, use `python -m manim` or check PATH
|
|
147
|
+
|
|
148
|
+
### Installation
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Install Manim Community
|
|
152
|
+
pip install manim
|
|
153
|
+
|
|
154
|
+
# Check installation
|
|
155
|
+
manim checkhealth
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Useful Commands
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
manim -pql scene.py Scene # Preview low quality (development)
|
|
162
|
+
manim -pqh scene.py Scene # Preview high quality
|
|
163
|
+
manim --format gif scene.py # Output as GIF
|
|
164
|
+
manim checkhealth # Verify installation
|
|
165
|
+
manim plugins -l # List plugins
|
|
166
|
+
```
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"""
|
|
2
|
+
3D Visualization Patterns for Manim Community
|
|
3
|
+
|
|
4
|
+
Demonstrates ThreeDScene, 3D axes, surfaces, and camera control.
|
|
5
|
+
Adapted from 3b1b patterns for ManimCE.
|
|
6
|
+
|
|
7
|
+
Run with: manim -pql 3d_visualization.py SceneName
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from manim import *
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Basic3DScene(ThreeDScene):
|
|
15
|
+
"""Basic 3D scene with shapes."""
|
|
16
|
+
|
|
17
|
+
def construct(self):
|
|
18
|
+
# Set camera orientation
|
|
19
|
+
self.set_camera_orientation(phi=60 * DEGREES, theta=-45 * DEGREES)
|
|
20
|
+
|
|
21
|
+
# 3D shapes
|
|
22
|
+
sphere = Sphere(radius=1, color=BLUE)
|
|
23
|
+
cube = Cube(side_length=1.5, color=RED, fill_opacity=0.7)
|
|
24
|
+
cone = Cone(base_radius=0.8, height=1.5, color=GREEN)
|
|
25
|
+
|
|
26
|
+
# Position shapes
|
|
27
|
+
sphere.shift(LEFT * 3)
|
|
28
|
+
cone.shift(RIGHT * 3)
|
|
29
|
+
|
|
30
|
+
self.play(Create(sphere), Create(cube), Create(cone))
|
|
31
|
+
self.wait()
|
|
32
|
+
|
|
33
|
+
# Rotate camera
|
|
34
|
+
self.begin_ambient_camera_rotation(rate=0.3)
|
|
35
|
+
self.wait(4)
|
|
36
|
+
self.stop_ambient_camera_rotation()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ThreeDAxesExample(ThreeDScene):
|
|
40
|
+
"""3D coordinate axes and plotting."""
|
|
41
|
+
|
|
42
|
+
def construct(self):
|
|
43
|
+
self.set_camera_orientation(phi=70 * DEGREES, theta=-45 * DEGREES)
|
|
44
|
+
|
|
45
|
+
# Create 3D axes
|
|
46
|
+
axes = ThreeDAxes(
|
|
47
|
+
x_range=[-3, 3, 1],
|
|
48
|
+
y_range=[-3, 3, 1],
|
|
49
|
+
z_range=[-2, 2, 1],
|
|
50
|
+
x_length=6,
|
|
51
|
+
y_length=6,
|
|
52
|
+
z_length=4,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Axis labels
|
|
56
|
+
x_label = axes.get_x_axis_label(r"x")
|
|
57
|
+
y_label = axes.get_y_axis_label(r"y")
|
|
58
|
+
z_label = axes.get_z_axis_label(r"z")
|
|
59
|
+
|
|
60
|
+
self.play(Create(axes))
|
|
61
|
+
self.add_fixed_orientation_mobjects(x_label, y_label, z_label)
|
|
62
|
+
self.wait()
|
|
63
|
+
|
|
64
|
+
# Add a point
|
|
65
|
+
point = Dot3D(axes.c2p(2, 1, 1.5), color=RED, radius=0.1)
|
|
66
|
+
self.play(Create(point))
|
|
67
|
+
|
|
68
|
+
# Camera rotation
|
|
69
|
+
self.begin_ambient_camera_rotation(rate=0.2)
|
|
70
|
+
self.wait(5)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ParametricSurfaceExample(ThreeDScene):
|
|
74
|
+
"""3D parametric surface visualization."""
|
|
75
|
+
|
|
76
|
+
def construct(self):
|
|
77
|
+
self.set_camera_orientation(phi=60 * DEGREES, theta=-60 * DEGREES)
|
|
78
|
+
|
|
79
|
+
axes = ThreeDAxes(
|
|
80
|
+
x_range=[-3, 3],
|
|
81
|
+
y_range=[-3, 3],
|
|
82
|
+
z_range=[-2, 2],
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Saddle surface: z = x^2 - y^2
|
|
86
|
+
surface = Surface(
|
|
87
|
+
lambda u, v: axes.c2p(u, v, u ** 2 - v ** 2),
|
|
88
|
+
u_range=[-2, 2],
|
|
89
|
+
v_range=[-2, 2],
|
|
90
|
+
resolution=(20, 20),
|
|
91
|
+
fill_opacity=0.7,
|
|
92
|
+
)
|
|
93
|
+
surface.set_color_by_gradient(BLUE, GREEN, YELLOW)
|
|
94
|
+
|
|
95
|
+
self.play(Create(axes))
|
|
96
|
+
self.play(Create(surface), run_time=2)
|
|
97
|
+
|
|
98
|
+
self.begin_ambient_camera_rotation(rate=0.15)
|
|
99
|
+
self.wait(5)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class SphereVisualization(ThreeDScene):
|
|
103
|
+
"""Sphere with parametric representation."""
|
|
104
|
+
|
|
105
|
+
def construct(self):
|
|
106
|
+
self.set_camera_orientation(phi=70 * DEGREES, theta=30 * DEGREES)
|
|
107
|
+
|
|
108
|
+
# Parametric sphere
|
|
109
|
+
sphere = Surface(
|
|
110
|
+
lambda u, v: np.array([
|
|
111
|
+
np.cos(v) * np.sin(u),
|
|
112
|
+
np.sin(v) * np.sin(u),
|
|
113
|
+
np.cos(u)
|
|
114
|
+
]),
|
|
115
|
+
u_range=[0, PI],
|
|
116
|
+
v_range=[0, 2 * PI],
|
|
117
|
+
resolution=(20, 40),
|
|
118
|
+
)
|
|
119
|
+
sphere.set_color_by_gradient(BLUE_E, BLUE, TEAL)
|
|
120
|
+
|
|
121
|
+
self.play(Create(sphere), run_time=2)
|
|
122
|
+
|
|
123
|
+
# Animate camera
|
|
124
|
+
self.begin_ambient_camera_rotation(rate=0.2)
|
|
125
|
+
self.wait(5)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class Function3DPlot(ThreeDScene):
|
|
129
|
+
"""Plotting z = f(x, y) surfaces."""
|
|
130
|
+
|
|
131
|
+
def construct(self):
|
|
132
|
+
self.set_camera_orientation(phi=65 * DEGREES, theta=-45 * DEGREES)
|
|
133
|
+
|
|
134
|
+
axes = ThreeDAxes(
|
|
135
|
+
x_range=[-3, 3],
|
|
136
|
+
y_range=[-3, 3],
|
|
137
|
+
z_range=[-1, 1],
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Sine wave surface
|
|
141
|
+
surface = Surface(
|
|
142
|
+
lambda u, v: axes.c2p(
|
|
143
|
+
u, v,
|
|
144
|
+
np.sin(np.sqrt(u ** 2 + v ** 2))
|
|
145
|
+
),
|
|
146
|
+
u_range=[-3, 3],
|
|
147
|
+
v_range=[-3, 3],
|
|
148
|
+
resolution=(30, 30),
|
|
149
|
+
)
|
|
150
|
+
surface.set_color_by_gradient(PURPLE, RED, ORANGE)
|
|
151
|
+
|
|
152
|
+
self.play(Create(axes))
|
|
153
|
+
self.play(Create(surface), run_time=2)
|
|
154
|
+
|
|
155
|
+
self.begin_ambient_camera_rotation(rate=0.1)
|
|
156
|
+
self.wait(6)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class VectorField3D(ThreeDScene):
|
|
160
|
+
"""3D vector field visualization."""
|
|
161
|
+
|
|
162
|
+
def construct(self):
|
|
163
|
+
self.set_camera_orientation(phi=60 * DEGREES, theta=-45 * DEGREES)
|
|
164
|
+
|
|
165
|
+
axes = ThreeDAxes(
|
|
166
|
+
x_range=[-3, 3],
|
|
167
|
+
y_range=[-3, 3],
|
|
168
|
+
z_range=[-3, 3],
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Create arrows representing a vector field
|
|
172
|
+
arrows = VGroup()
|
|
173
|
+
for x in np.arange(-2, 3, 1):
|
|
174
|
+
for y in np.arange(-2, 3, 1):
|
|
175
|
+
for z in np.arange(-2, 3, 1):
|
|
176
|
+
# Vector field: F = (-y, x, z)
|
|
177
|
+
start = axes.c2p(x, y, z)
|
|
178
|
+
direction = np.array([-y, x, z]) * 0.3
|
|
179
|
+
end = start + direction
|
|
180
|
+
|
|
181
|
+
arrow = Arrow3D(
|
|
182
|
+
start=start,
|
|
183
|
+
end=end,
|
|
184
|
+
color=interpolate_color(
|
|
185
|
+
BLUE, RED,
|
|
186
|
+
(z + 2) / 4
|
|
187
|
+
),
|
|
188
|
+
)
|
|
189
|
+
arrows.add(arrow)
|
|
190
|
+
|
|
191
|
+
self.play(Create(axes))
|
|
192
|
+
self.play(LaggedStart(*[Create(a) for a in arrows], lag_ratio=0.02))
|
|
193
|
+
|
|
194
|
+
self.begin_ambient_camera_rotation(rate=0.1)
|
|
195
|
+
self.wait(5)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class CameraMovement3D(ThreeDScene):
|
|
199
|
+
"""Demonstrating 3D camera controls."""
|
|
200
|
+
|
|
201
|
+
def construct(self):
|
|
202
|
+
# Start with a default view
|
|
203
|
+
self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
|
|
204
|
+
|
|
205
|
+
# Create a 3D object
|
|
206
|
+
torus = Torus(
|
|
207
|
+
major_radius=2,
|
|
208
|
+
minor_radius=0.5,
|
|
209
|
+
color=BLUE,
|
|
210
|
+
fill_opacity=0.8
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
self.play(Create(torus))
|
|
214
|
+
self.wait()
|
|
215
|
+
|
|
216
|
+
# Move camera to different angles
|
|
217
|
+
self.move_camera(phi=30 * DEGREES, theta=0, run_time=2)
|
|
218
|
+
self.wait()
|
|
219
|
+
|
|
220
|
+
self.move_camera(phi=90 * DEGREES, theta=90 * DEGREES, run_time=2)
|
|
221
|
+
self.wait()
|
|
222
|
+
|
|
223
|
+
# Zoom by adjusting frame
|
|
224
|
+
self.move_camera(zoom=1.5, run_time=1)
|
|
225
|
+
self.wait()
|
|
226
|
+
|
|
227
|
+
self.move_camera(zoom=0.7, run_time=1)
|
|
228
|
+
self.wait()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class Line3DExample(ThreeDScene):
|
|
232
|
+
"""3D lines and curves."""
|
|
233
|
+
|
|
234
|
+
def construct(self):
|
|
235
|
+
self.set_camera_orientation(phi=70 * DEGREES, theta=-45 * DEGREES)
|
|
236
|
+
|
|
237
|
+
axes = ThreeDAxes()
|
|
238
|
+
|
|
239
|
+
# 3D helix
|
|
240
|
+
helix = ParametricFunction(
|
|
241
|
+
lambda t: np.array([
|
|
242
|
+
np.cos(t),
|
|
243
|
+
np.sin(t),
|
|
244
|
+
t / 4
|
|
245
|
+
]),
|
|
246
|
+
t_range=[0, 4 * PI],
|
|
247
|
+
color=YELLOW,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
# Line in 3D
|
|
251
|
+
line = Line3D(
|
|
252
|
+
start=axes.c2p(-2, -2, -1),
|
|
253
|
+
end=axes.c2p(2, 2, 1),
|
|
254
|
+
color=RED,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
self.play(Create(axes))
|
|
258
|
+
self.play(Create(helix), run_time=2)
|
|
259
|
+
self.play(Create(line))
|
|
260
|
+
|
|
261
|
+
self.begin_ambient_camera_rotation(rate=0.15)
|
|
262
|
+
self.wait(5)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class TextIn3D(ThreeDScene):
|
|
266
|
+
"""Text and math in 3D scenes."""
|
|
267
|
+
|
|
268
|
+
def construct(self):
|
|
269
|
+
self.set_camera_orientation(phi=60 * DEGREES, theta=-45 * DEGREES)
|
|
270
|
+
|
|
271
|
+
axes = ThreeDAxes()
|
|
272
|
+
|
|
273
|
+
# 3D text (stays fixed to camera)
|
|
274
|
+
title = Text("3D Visualization", font_size=48)
|
|
275
|
+
title.to_corner(UL)
|
|
276
|
+
self.add_fixed_in_frame_mobjects(title)
|
|
277
|
+
|
|
278
|
+
# Math label fixed to camera
|
|
279
|
+
equation = MathTex(r"z = x^2 + y^2")
|
|
280
|
+
equation.to_corner(UR)
|
|
281
|
+
self.add_fixed_in_frame_mobjects(equation)
|
|
282
|
+
|
|
283
|
+
# Surface
|
|
284
|
+
paraboloid = Surface(
|
|
285
|
+
lambda u, v: axes.c2p(u, v, u ** 2 + v ** 2),
|
|
286
|
+
u_range=[-1.5, 1.5],
|
|
287
|
+
v_range=[-1.5, 1.5],
|
|
288
|
+
resolution=(15, 15),
|
|
289
|
+
)
|
|
290
|
+
paraboloid.set_color_by_gradient(BLUE, GREEN)
|
|
291
|
+
|
|
292
|
+
self.play(Write(title), Write(equation))
|
|
293
|
+
self.play(Create(axes))
|
|
294
|
+
self.play(Create(paraboloid))
|
|
295
|
+
|
|
296
|
+
self.begin_ambient_camera_rotation(rate=0.1)
|
|
297
|
+
self.wait(5)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class AnimatedSurface(ThreeDScene):
|
|
301
|
+
"""Surface that changes over time."""
|
|
302
|
+
|
|
303
|
+
def construct(self):
|
|
304
|
+
self.set_camera_orientation(phi=65 * DEGREES, theta=-45 * DEGREES)
|
|
305
|
+
|
|
306
|
+
axes = ThreeDAxes(
|
|
307
|
+
x_range=[-3, 3],
|
|
308
|
+
y_range=[-3, 3],
|
|
309
|
+
z_range=[-2, 2],
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# Time parameter
|
|
313
|
+
time = ValueTracker(0)
|
|
314
|
+
|
|
315
|
+
# Animated wave surface
|
|
316
|
+
surface = always_redraw(
|
|
317
|
+
lambda: Surface(
|
|
318
|
+
lambda u, v: axes.c2p(
|
|
319
|
+
u, v,
|
|
320
|
+
np.sin(np.sqrt(u ** 2 + v ** 2) - time.get_value())
|
|
321
|
+
),
|
|
322
|
+
u_range=[-3, 3],
|
|
323
|
+
v_range=[-3, 3],
|
|
324
|
+
resolution=(25, 25),
|
|
325
|
+
).set_color_by_gradient(BLUE, TEAL)
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
self.add(axes, surface)
|
|
329
|
+
|
|
330
|
+
# Animate
|
|
331
|
+
self.play(
|
|
332
|
+
time.animate.set_value(4 * PI),
|
|
333
|
+
run_time=8,
|
|
334
|
+
rate_func=linear
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class MultipleObjects3D(ThreeDScene):
|
|
339
|
+
"""Combining multiple 3D objects."""
|
|
340
|
+
|
|
341
|
+
def construct(self):
|
|
342
|
+
self.set_camera_orientation(phi=60 * DEGREES, theta=-30 * DEGREES)
|
|
343
|
+
|
|
344
|
+
# Create various 3D shapes
|
|
345
|
+
sphere = Sphere(radius=0.5, color=RED).shift(LEFT * 2 + UP)
|
|
346
|
+
cube = Cube(side_length=0.8, color=BLUE).shift(RIGHT * 2)
|
|
347
|
+
cylinder = Cylinder(
|
|
348
|
+
radius=0.4,
|
|
349
|
+
height=1.2,
|
|
350
|
+
color=GREEN
|
|
351
|
+
).shift(DOWN + LEFT)
|
|
352
|
+
|
|
353
|
+
# Arrows connecting them
|
|
354
|
+
arrow1 = Arrow3D(
|
|
355
|
+
start=sphere.get_center(),
|
|
356
|
+
end=cube.get_center(),
|
|
357
|
+
color=YELLOW
|
|
358
|
+
)
|
|
359
|
+
arrow2 = Arrow3D(
|
|
360
|
+
start=cube.get_center(),
|
|
361
|
+
end=cylinder.get_center(),
|
|
362
|
+
color=YELLOW
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
self.play(
|
|
366
|
+
Create(sphere),
|
|
367
|
+
Create(cube),
|
|
368
|
+
Create(cylinder),
|
|
369
|
+
)
|
|
370
|
+
self.play(Create(arrow1), Create(arrow2))
|
|
371
|
+
|
|
372
|
+
self.begin_ambient_camera_rotation(rate=0.2)
|
|
373
|
+
self.wait(5)
|