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,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: animation-groups
|
|
3
|
+
description: AnimationGroup, LaggedStart, Succession for complex animation sequences
|
|
4
|
+
metadata:
|
|
5
|
+
tags: animationgroup, laggedstart, succession, lag_ratio, sequence
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Animation Groups
|
|
9
|
+
|
|
10
|
+
Control how multiple animations play together.
|
|
11
|
+
|
|
12
|
+
## AnimationGroup
|
|
13
|
+
|
|
14
|
+
Play multiple animations with controlled timing.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
from manim import *
|
|
18
|
+
|
|
19
|
+
class AnimationGroupExample(Scene):
|
|
20
|
+
def construct(self):
|
|
21
|
+
circles = VGroup(*[Circle() for _ in range(5)]).arrange(RIGHT)
|
|
22
|
+
|
|
23
|
+
# All animations play simultaneously (lag_ratio=0)
|
|
24
|
+
self.play(AnimationGroup(
|
|
25
|
+
*[Create(c) for c in circles],
|
|
26
|
+
lag_ratio=0
|
|
27
|
+
))
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### lag_ratio Parameter
|
|
31
|
+
|
|
32
|
+
Controls the delay between animation starts:
|
|
33
|
+
- `lag_ratio=0`: All start simultaneously
|
|
34
|
+
- `lag_ratio=0.5`: Each starts when previous is 50% complete
|
|
35
|
+
- `lag_ratio=1`: Each starts when previous finishes (sequential)
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
class LagRatioDemo(Scene):
|
|
39
|
+
def construct(self):
|
|
40
|
+
squares = VGroup(*[Square() for _ in range(4)]).arrange(RIGHT)
|
|
41
|
+
|
|
42
|
+
# Staggered start - each begins when previous is 25% done
|
|
43
|
+
self.play(AnimationGroup(
|
|
44
|
+
*[FadeIn(s) for s in squares],
|
|
45
|
+
lag_ratio=0.25,
|
|
46
|
+
run_time=2
|
|
47
|
+
))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## LaggedStart
|
|
51
|
+
|
|
52
|
+
Convenience class with default `lag_ratio=0.05` (5% overlap).
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
class LaggedStartExample(Scene):
|
|
56
|
+
def construct(self):
|
|
57
|
+
dots = VGroup(*[Dot() for _ in range(10)]).arrange(RIGHT)
|
|
58
|
+
|
|
59
|
+
# Rapid staggered animation
|
|
60
|
+
self.play(LaggedStart(
|
|
61
|
+
*[GrowFromCenter(d) for d in dots],
|
|
62
|
+
lag_ratio=0.1
|
|
63
|
+
))
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Common LaggedStart Patterns
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# Staggered fade in
|
|
70
|
+
self.play(LaggedStart(*[FadeIn(m) for m in mobjects], lag_ratio=0.2))
|
|
71
|
+
|
|
72
|
+
# Wave effect
|
|
73
|
+
self.play(LaggedStart(
|
|
74
|
+
*[m.animate.shift(UP * 0.5) for m in mobjects],
|
|
75
|
+
lag_ratio=0.1
|
|
76
|
+
))
|
|
77
|
+
|
|
78
|
+
# Staggered color change
|
|
79
|
+
self.play(LaggedStart(
|
|
80
|
+
*[m.animate.set_color(RED) for m in mobjects],
|
|
81
|
+
lag_ratio=0.15
|
|
82
|
+
))
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Succession
|
|
86
|
+
|
|
87
|
+
Play animations one after another (equivalent to `lag_ratio=1`).
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
class SuccessionExample(Scene):
|
|
91
|
+
def construct(self):
|
|
92
|
+
circle = Circle().shift(LEFT * 2)
|
|
93
|
+
square = Square()
|
|
94
|
+
triangle = Triangle().shift(RIGHT * 2)
|
|
95
|
+
|
|
96
|
+
# Animations play in sequence
|
|
97
|
+
self.play(Succession(
|
|
98
|
+
Create(circle),
|
|
99
|
+
Create(square),
|
|
100
|
+
Create(triangle)
|
|
101
|
+
))
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Succession vs Multiple play() Calls
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
# These are equivalent:
|
|
108
|
+
|
|
109
|
+
# Using Succession
|
|
110
|
+
self.play(Succession(
|
|
111
|
+
Create(circle),
|
|
112
|
+
Create(square)
|
|
113
|
+
))
|
|
114
|
+
|
|
115
|
+
# Using separate play calls
|
|
116
|
+
self.play(Create(circle))
|
|
117
|
+
self.play(Create(square))
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Succession is useful when you want to treat sequential animations as a single unit.
|
|
121
|
+
|
|
122
|
+
## Combining Group Types
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
class CombinedExample(Scene):
|
|
126
|
+
def construct(self):
|
|
127
|
+
group1 = VGroup(*[Circle() for _ in range(3)]).arrange(RIGHT).shift(UP)
|
|
128
|
+
group2 = VGroup(*[Square() for _ in range(3)]).arrange(RIGHT).shift(DOWN)
|
|
129
|
+
|
|
130
|
+
# First group appears with stagger, then second group
|
|
131
|
+
self.play(Succession(
|
|
132
|
+
LaggedStart(*[Create(c) for c in group1], lag_ratio=0.2),
|
|
133
|
+
LaggedStart(*[Create(s) for s in group2], lag_ratio=0.2)
|
|
134
|
+
))
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## LaggedStartMap
|
|
138
|
+
|
|
139
|
+
Apply an animation to all submobjects of a mobject with staggered timing.
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
class LaggedStartMapExample(Scene):
|
|
143
|
+
def construct(self):
|
|
144
|
+
dots = VGroup(*[Dot(radius=0.16) for _ in range(35)]).arrange_in_grid(rows=5, cols=7)
|
|
145
|
+
|
|
146
|
+
# Apply FadeIn to all dots with stagger
|
|
147
|
+
self.play(LaggedStartMap(FadeIn, dots, lag_ratio=0.1))
|
|
148
|
+
self.wait(0.5)
|
|
149
|
+
|
|
150
|
+
# Change color with stagger using LaggedStart
|
|
151
|
+
self.play(LaggedStart(
|
|
152
|
+
*[dot.animate.set_color(YELLOW) for dot in dots],
|
|
153
|
+
lag_ratio=0.05
|
|
154
|
+
))
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
LaggedStartMap is cleaner for applying the same animation to each submobject. For property changes, use LaggedStart with `.animate`.
|
|
158
|
+
|
|
159
|
+
## AnimationGroup with run_time
|
|
160
|
+
|
|
161
|
+
The total `run_time` is distributed among animations based on `lag_ratio`.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
self.play(AnimationGroup(
|
|
165
|
+
*[Create(c) for c in circles],
|
|
166
|
+
lag_ratio=0.5,
|
|
167
|
+
run_time=4 # Total duration is 4 seconds
|
|
168
|
+
))
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Practical Examples
|
|
172
|
+
|
|
173
|
+
### Text Appearing Word by Word
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
class WordByWord(Scene):
|
|
177
|
+
def construct(self):
|
|
178
|
+
words = VGroup(
|
|
179
|
+
Text("Hello"),
|
|
180
|
+
Text("World"),
|
|
181
|
+
Text("!")
|
|
182
|
+
).arrange(RIGHT)
|
|
183
|
+
|
|
184
|
+
self.play(LaggedStart(
|
|
185
|
+
*[Write(w) for w in words],
|
|
186
|
+
lag_ratio=0.5
|
|
187
|
+
))
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Grid Animation
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
class GridAnimation(Scene):
|
|
194
|
+
def construct(self):
|
|
195
|
+
grid = VGroup(*[
|
|
196
|
+
Square().scale(0.3)
|
|
197
|
+
for _ in range(25)
|
|
198
|
+
]).arrange_in_grid(5, 5)
|
|
199
|
+
|
|
200
|
+
# Diagonal wave effect
|
|
201
|
+
self.play(LaggedStart(
|
|
202
|
+
*[GrowFromCenter(s) for s in grid],
|
|
203
|
+
lag_ratio=0.05
|
|
204
|
+
))
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Best Practices
|
|
208
|
+
|
|
209
|
+
1. **Use LaggedStart for visual polish** - Staggered animations look more dynamic
|
|
210
|
+
2. **Keep lag_ratio small (0.05-0.2)** - Too high feels slow
|
|
211
|
+
3. **Use Succession for distinct steps** - When animations are conceptually separate
|
|
212
|
+
4. **Adjust run_time with lag_ratio** - More items may need longer total time
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: animations
|
|
3
|
+
description: Animation classes, playing animations, and animation timing in Manim
|
|
4
|
+
metadata:
|
|
5
|
+
tags: animation, play, run_time, rate_func, animate
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Animations in Manim
|
|
9
|
+
|
|
10
|
+
Animations interpolate mobjects between states over time. They are played using `self.play()`.
|
|
11
|
+
|
|
12
|
+
## The .animate Syntax
|
|
13
|
+
|
|
14
|
+
The most common way to animate is using the `.animate` property:
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# Move a square to the right
|
|
18
|
+
self.play(square.animate.shift(RIGHT))
|
|
19
|
+
|
|
20
|
+
# Scale up
|
|
21
|
+
self.play(circle.animate.scale(2))
|
|
22
|
+
|
|
23
|
+
# Change color
|
|
24
|
+
self.play(text.animate.set_color(RED))
|
|
25
|
+
|
|
26
|
+
# Chain multiple changes
|
|
27
|
+
self.play(square.animate.shift(RIGHT).rotate(PI/4).set_color(BLUE))
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Animation Parameters
|
|
31
|
+
|
|
32
|
+
### run_time
|
|
33
|
+
Controls animation duration in seconds (default: 1).
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
self.play(Create(circle), run_time=2) # 2 second animation
|
|
37
|
+
self.play(Create(circle), run_time=0.5) # Half second
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### rate_func
|
|
41
|
+
Controls the animation's timing curve (easing).
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from manim import smooth, linear, there_and_back
|
|
45
|
+
|
|
46
|
+
self.play(square.animate.shift(RIGHT), rate_func=smooth)
|
|
47
|
+
self.play(square.animate.shift(RIGHT), rate_func=linear)
|
|
48
|
+
self.play(square.animate.shift(RIGHT), rate_func=there_and_back)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Playing Multiple Animations
|
|
52
|
+
|
|
53
|
+
### Simultaneously
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
# All play at the same time
|
|
57
|
+
self.play(
|
|
58
|
+
Create(circle),
|
|
59
|
+
FadeIn(square),
|
|
60
|
+
Write(text)
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Sequentially
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
# One after another
|
|
68
|
+
self.play(Create(circle))
|
|
69
|
+
self.play(FadeIn(square))
|
|
70
|
+
self.play(Write(text))
|
|
71
|
+
|
|
72
|
+
# Or use Succession
|
|
73
|
+
self.play(Succession(
|
|
74
|
+
Create(circle),
|
|
75
|
+
FadeIn(square),
|
|
76
|
+
Write(text)
|
|
77
|
+
))
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Common Animation Classes
|
|
81
|
+
|
|
82
|
+
### Creation Animations
|
|
83
|
+
```python
|
|
84
|
+
Create(mobject) # Draw the mobject progressively
|
|
85
|
+
Write(text) # Write text/equations
|
|
86
|
+
FadeIn(mobject) # Fade in from transparent
|
|
87
|
+
DrawBorderThenFill(mob) # Draw outline, then fill
|
|
88
|
+
GrowFromCenter(mobject) # Grow from center point
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Removal Animations
|
|
92
|
+
```python
|
|
93
|
+
FadeOut(mobject) # Fade to transparent
|
|
94
|
+
Uncreate(mobject) # Reverse of Create
|
|
95
|
+
ShrinkToCenter(mobject) # Shrink to center and disappear
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Transform Animations
|
|
99
|
+
```python
|
|
100
|
+
Transform(mob1, mob2) # Morph mob1 into mob2
|
|
101
|
+
ReplacementTransform(mob1, mob2) # Replace mob1 with mob2
|
|
102
|
+
TransformFromCopy(mob1, mob2) # Keep mob1, create mob2
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Movement Animations
|
|
106
|
+
```python
|
|
107
|
+
MoveToTarget(mobject) # Move to preset target
|
|
108
|
+
Rotate(mobject, angle) # Rotate by angle
|
|
109
|
+
Circumscribe(mobject) # Draw attention with circle
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Animation vs Instant Changes
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# Animated change (visible transition)
|
|
116
|
+
self.play(circle.animate.set_color(RED))
|
|
117
|
+
|
|
118
|
+
# Instant change (no animation)
|
|
119
|
+
circle.set_color(RED)
|
|
120
|
+
self.add(circle)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Best Practices
|
|
124
|
+
|
|
125
|
+
1. **Use .animate for simple transformations** - Cleaner than explicit Animation classes
|
|
126
|
+
2. **Keep run_time reasonable** - 0.5-2 seconds for most animations
|
|
127
|
+
3. **Use rate_func for polish** - `smooth` is usually better than `linear`
|
|
128
|
+
4. **Group related animations** - Play simultaneously when conceptually related
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-pitfalls
|
|
3
|
+
description: Common ManimCE API mistakes that cause runtime errors
|
|
4
|
+
metadata:
|
|
5
|
+
tags: errors, pitfalls, brace, laggedstartmap, font_size, debugging
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Common API Pitfalls
|
|
9
|
+
|
|
10
|
+
These mistakes compile fine but crash at render time. Avoid them.
|
|
11
|
+
|
|
12
|
+
## Brace.get_text() Does NOT Accept font_size
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
# BAD — crashes with "next_to() got unexpected keyword argument 'font_size'"
|
|
16
|
+
brace = Brace(mobject, DOWN)
|
|
17
|
+
label = brace.get_text("Width", font_size=24) # WRONG
|
|
18
|
+
|
|
19
|
+
# GOOD — set font_size on the Text object afterward
|
|
20
|
+
brace = Brace(mobject, DOWN)
|
|
21
|
+
label = brace.get_text("Width")
|
|
22
|
+
label.scale(0.6) # Scale instead
|
|
23
|
+
|
|
24
|
+
# GOOD — or create the text separately
|
|
25
|
+
label = Text("Width", font_size=24).next_to(brace, DOWN, buff=0.1)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`get_text()` only accepts `*text` and `**kwargs` that are passed to `next_to()`. It does NOT accept `font_size`, `color`, or other Text kwargs.
|
|
29
|
+
|
|
30
|
+
## LaggedStartMap Requires a VGroup, Not Loose Mobjects
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
# BAD — crashes with "Write.__init__() takes from 2 to 4 positional arguments but N were given"
|
|
34
|
+
labels = [Text("A"), Text("B"), Text("C")]
|
|
35
|
+
self.play(LaggedStartMap(Write, labels)) # WRONG — list, not VGroup
|
|
36
|
+
|
|
37
|
+
# Also BAD — VGroup with nested submobjects gets flattened
|
|
38
|
+
labels_group = VGroup(text1, text2, text3) # Each text has many submobjects
|
|
39
|
+
self.play(LaggedStartMap(Write, labels_group)) # Iterates submobjects of submobjects!
|
|
40
|
+
|
|
41
|
+
# GOOD — use LaggedStart with explicit animation list
|
|
42
|
+
self.play(LaggedStart(*[Write(t) for t in labels], lag_ratio=0.3))
|
|
43
|
+
|
|
44
|
+
# GOOD — LaggedStartMap with simple mobjects (Dot, Circle, Square)
|
|
45
|
+
dots = VGroup(*[Dot() for _ in range(10)]).arrange(RIGHT)
|
|
46
|
+
self.play(LaggedStartMap(FadeIn, dots, lag_ratio=0.1)) # Each dot is a single submobject
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Rule of thumb**: Use `LaggedStartMap` only with VGroups of simple mobjects (Dot, Circle, Square). For Text, MathTex, or complex mobjects, use `LaggedStart(*[Anim(m) for m in items])`.
|
|
50
|
+
|
|
51
|
+
## MathTex Indexing Is Per LaTeX Group
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
# BAD — index out of range or wrong element
|
|
55
|
+
eq = MathTex("a^2 + b^2 = c^2")
|
|
56
|
+
eq[1].set_color(RED) # Only 1 element! The whole string is one group
|
|
57
|
+
|
|
58
|
+
# GOOD — split into separate strings for indexing
|
|
59
|
+
eq = MathTex("a^2", "+", "b^2", "=", "c^2")
|
|
60
|
+
eq[0].set_color(RED) # "a^2"
|
|
61
|
+
eq[2].set_color(BLUE) # "b^2"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Transform Requires Same Type OR Use ReplacementTransform
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
# BAD — unexpected behavior
|
|
68
|
+
self.play(Transform(old_text, new_equation)) # Text → MathTex can glitch
|
|
69
|
+
|
|
70
|
+
# GOOD
|
|
71
|
+
self.play(ReplacementTransform(old_text, new_equation))
|
|
72
|
+
# OR
|
|
73
|
+
self.play(FadeOut(old_text), FadeIn(new_equation))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## VGroup.arrange() Returns Self — Don't Forget to Use It
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# BAD — items not arranged
|
|
80
|
+
items = VGroup(circle, square, triangle)
|
|
81
|
+
items.arrange(RIGHT) # Works, but easy to forget
|
|
82
|
+
|
|
83
|
+
# Common mistake: creating items then forgetting to arrange
|
|
84
|
+
group = VGroup(*[Square() for _ in range(5)])
|
|
85
|
+
# Oops — all squares overlap at origin!
|
|
86
|
+
|
|
87
|
+
# GOOD
|
|
88
|
+
group = VGroup(*[Square() for _ in range(5)]).arrange(RIGHT, buff=0.3)
|
|
89
|
+
```
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: axes
|
|
3
|
+
description: Axes, NumberPlane, and coordinate systems in Manim
|
|
4
|
+
metadata:
|
|
5
|
+
tags: axes, numberplane, coordinate, grid, numberline
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Coordinate Systems
|
|
9
|
+
|
|
10
|
+
Create axes, grids, and number lines for mathematical visualizations.
|
|
11
|
+
|
|
12
|
+
## Axes
|
|
13
|
+
|
|
14
|
+
Basic 2D coordinate axes.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
from manim import *
|
|
18
|
+
|
|
19
|
+
class AxesExample(Scene):
|
|
20
|
+
def construct(self):
|
|
21
|
+
# Default axes
|
|
22
|
+
axes = Axes()
|
|
23
|
+
self.add(axes)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Customizing Axes
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
class CustomAxes(Scene):
|
|
30
|
+
def construct(self):
|
|
31
|
+
axes = Axes(
|
|
32
|
+
x_range=[-5, 5, 1], # [min, max, step]
|
|
33
|
+
y_range=[-3, 3, 1],
|
|
34
|
+
x_length=10, # Physical length on screen
|
|
35
|
+
y_length=6,
|
|
36
|
+
axis_config={
|
|
37
|
+
"color": BLUE,
|
|
38
|
+
"include_tip": True,
|
|
39
|
+
"include_numbers": True,
|
|
40
|
+
},
|
|
41
|
+
x_axis_config={
|
|
42
|
+
"numbers_to_include": [-4, -2, 0, 2, 4],
|
|
43
|
+
},
|
|
44
|
+
y_axis_config={
|
|
45
|
+
"numbers_to_include": [-2, 0, 2],
|
|
46
|
+
},
|
|
47
|
+
)
|
|
48
|
+
self.add(axes)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Adding Labels
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
class AxesLabels(Scene):
|
|
55
|
+
def construct(self):
|
|
56
|
+
axes = Axes(x_range=[-5, 5], y_range=[-3, 3])
|
|
57
|
+
|
|
58
|
+
# Add axis labels
|
|
59
|
+
x_label = axes.get_x_axis_label("x")
|
|
60
|
+
y_label = axes.get_y_axis_label("y")
|
|
61
|
+
|
|
62
|
+
# Custom labels
|
|
63
|
+
x_label = axes.get_x_axis_label(MathTex(r"\theta"))
|
|
64
|
+
y_label = axes.get_y_axis_label(MathTex(r"f(\theta)"))
|
|
65
|
+
|
|
66
|
+
self.add(axes, x_label, y_label)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## NumberPlane
|
|
70
|
+
|
|
71
|
+
Grid with axes - shows coordinate lines.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
class NumberPlaneExample(Scene):
|
|
75
|
+
def construct(self):
|
|
76
|
+
# Default plane
|
|
77
|
+
plane = NumberPlane()
|
|
78
|
+
self.add(plane)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Customizing NumberPlane
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
class CustomPlane(Scene):
|
|
85
|
+
def construct(self):
|
|
86
|
+
plane = NumberPlane(
|
|
87
|
+
x_range=[-4, 4, 1],
|
|
88
|
+
y_range=[-3, 3, 1],
|
|
89
|
+
x_length=8,
|
|
90
|
+
y_length=6,
|
|
91
|
+
background_line_style={
|
|
92
|
+
"stroke_color": BLUE_D,
|
|
93
|
+
"stroke_width": 1,
|
|
94
|
+
"stroke_opacity": 0.5,
|
|
95
|
+
},
|
|
96
|
+
axis_config={
|
|
97
|
+
"color": WHITE,
|
|
98
|
+
},
|
|
99
|
+
)
|
|
100
|
+
self.add(plane)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## ComplexPlane
|
|
104
|
+
|
|
105
|
+
For visualizing complex numbers.
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
class ComplexPlaneExample(Scene):
|
|
109
|
+
def construct(self):
|
|
110
|
+
plane = ComplexPlane()
|
|
111
|
+
|
|
112
|
+
# Plot complex number
|
|
113
|
+
z = complex(2, 1) # 2 + i
|
|
114
|
+
dot = Dot(plane.n2p(z), color=YELLOW)
|
|
115
|
+
label = MathTex("2+i").next_to(dot, UR)
|
|
116
|
+
|
|
117
|
+
self.add(plane, dot, label)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## NumberLine
|
|
121
|
+
|
|
122
|
+
Single axis line.
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
class NumberLineExample(Scene):
|
|
126
|
+
def construct(self):
|
|
127
|
+
line = NumberLine(
|
|
128
|
+
x_range=[-5, 5, 1],
|
|
129
|
+
length=10,
|
|
130
|
+
include_numbers=True,
|
|
131
|
+
include_tip=True,
|
|
132
|
+
)
|
|
133
|
+
self.add(line)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Coordinate Conversions
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
class CoordinateConversion(Scene):
|
|
140
|
+
def construct(self):
|
|
141
|
+
axes = Axes(x_range=[-5, 5], y_range=[-3, 3])
|
|
142
|
+
|
|
143
|
+
# Convert coordinates to screen position
|
|
144
|
+
point = axes.c2p(2, 1) # coords_to_point: (2, 1) -> screen position
|
|
145
|
+
|
|
146
|
+
# Convert screen position to coordinates
|
|
147
|
+
coords = axes.p2c(point) # point_to_coords: screen -> (x, y)
|
|
148
|
+
|
|
149
|
+
dot = Dot(point, color=RED)
|
|
150
|
+
self.add(axes, dot)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Shorthand Methods
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
axes = Axes()
|
|
157
|
+
|
|
158
|
+
# c2p = coords_to_point
|
|
159
|
+
axes.c2p(x, y)
|
|
160
|
+
|
|
161
|
+
# p2c = point_to_coords
|
|
162
|
+
axes.p2c(point)
|
|
163
|
+
|
|
164
|
+
# i2gp = input_to_graph_point (for graphs)
|
|
165
|
+
axes.i2gp(x, graph)
|
|
166
|
+
|
|
167
|
+
# For NumberPlane/ComplexPlane
|
|
168
|
+
plane.n2p(complex_number) # number_to_point
|
|
169
|
+
plane.p2n(point) # point_to_number
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## ThreeDAxes
|
|
173
|
+
|
|
174
|
+
For 3D visualizations.
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
class ThreeDAxesExample(ThreeDScene):
|
|
178
|
+
def construct(self):
|
|
179
|
+
axes = ThreeDAxes(
|
|
180
|
+
x_range=[-4, 4, 1],
|
|
181
|
+
y_range=[-4, 4, 1],
|
|
182
|
+
z_range=[-4, 4, 1],
|
|
183
|
+
x_length=8,
|
|
184
|
+
y_length=8,
|
|
185
|
+
z_length=6,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
|
|
189
|
+
self.add(axes)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Plotting Points
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
class PlotPoints(Scene):
|
|
196
|
+
def construct(self):
|
|
197
|
+
axes = Axes(x_range=[-5, 5], y_range=[-3, 3])
|
|
198
|
+
|
|
199
|
+
points = [(1, 2), (-2, 1), (3, -1), (0, 2)]
|
|
200
|
+
dots = VGroup(*[
|
|
201
|
+
Dot(axes.c2p(x, y), color=YELLOW)
|
|
202
|
+
for x, y in points
|
|
203
|
+
])
|
|
204
|
+
|
|
205
|
+
self.add(axes, dots)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Best Practices
|
|
209
|
+
|
|
210
|
+
1. **Set appropriate ranges** - Don't include unnecessary empty space
|
|
211
|
+
2. **Match x_length/y_length to range ratio** - Prevents distortion
|
|
212
|
+
3. **Use NumberPlane for transformations** - Grid shows distortion clearly
|
|
213
|
+
4. **Use c2p for all coordinate work** - Don't manually convert
|
|
214
|
+
5. **Include numbers sparingly** - Too many numbers clutter the display
|