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
|
+
Basic Animation Patterns for Manim Community
|
|
3
|
+
|
|
4
|
+
This file demonstrates fundamental animation techniques adapted from 3b1b patterns.
|
|
5
|
+
Run with: manim -pql basic_animations.py SceneName
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from manim import *
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ShapeCreation(Scene):
|
|
12
|
+
"""Demonstrates various ways to create and animate shapes."""
|
|
13
|
+
|
|
14
|
+
def construct(self):
|
|
15
|
+
# Create shapes
|
|
16
|
+
circle = Circle(radius=1, color=BLUE, fill_opacity=0.5)
|
|
17
|
+
square = Square(side_length=2, color=RED)
|
|
18
|
+
triangle = Triangle(color=GREEN, fill_opacity=0.8)
|
|
19
|
+
|
|
20
|
+
# Arrange shapes
|
|
21
|
+
shapes = VGroup(circle, square, triangle).arrange(RIGHT, buff=1)
|
|
22
|
+
|
|
23
|
+
# Different creation animations
|
|
24
|
+
self.play(Create(circle)) # Draw outline progressively
|
|
25
|
+
self.play(DrawBorderThenFill(square)) # Border first, then fill
|
|
26
|
+
self.play(GrowFromCenter(triangle)) # Grow from center point
|
|
27
|
+
|
|
28
|
+
self.wait()
|
|
29
|
+
|
|
30
|
+
# Transform between shapes
|
|
31
|
+
self.play(Transform(circle, square.copy().shift(UP * 2)))
|
|
32
|
+
|
|
33
|
+
self.wait()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TextAnimations(Scene):
|
|
37
|
+
"""Demonstrates text and LaTeX animations."""
|
|
38
|
+
|
|
39
|
+
def construct(self):
|
|
40
|
+
# Plain text
|
|
41
|
+
title = Text("Manim Community", font_size=72, color=BLUE)
|
|
42
|
+
self.play(Write(title))
|
|
43
|
+
self.wait()
|
|
44
|
+
|
|
45
|
+
# Move title up
|
|
46
|
+
self.play(title.animate.to_edge(UP))
|
|
47
|
+
|
|
48
|
+
# LaTeX math
|
|
49
|
+
equation = MathTex(r"e^{i\pi} + 1 = 0", font_size=64)
|
|
50
|
+
self.play(Write(equation))
|
|
51
|
+
self.wait()
|
|
52
|
+
|
|
53
|
+
# Transform equation
|
|
54
|
+
expanded = MathTex(r"e^{i\pi} = -1", font_size=64)
|
|
55
|
+
self.play(TransformMatchingTex(equation, expanded))
|
|
56
|
+
|
|
57
|
+
self.wait()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class LaggedAnimations(Scene):
|
|
61
|
+
"""Demonstrates staggered animations using LaggedStart patterns."""
|
|
62
|
+
|
|
63
|
+
def construct(self):
|
|
64
|
+
# Create a grid of dots
|
|
65
|
+
dots = VGroup(*[
|
|
66
|
+
Dot(radius=0.15, color=interpolate_color(BLUE, RED, i / 24))
|
|
67
|
+
for i in range(25)
|
|
68
|
+
]).arrange_in_grid(rows=5, cols=5, buff=0.5)
|
|
69
|
+
|
|
70
|
+
# Staggered fade in
|
|
71
|
+
self.play(
|
|
72
|
+
LaggedStart(*[FadeIn(dot, scale=0.5) for dot in dots], lag_ratio=0.1)
|
|
73
|
+
)
|
|
74
|
+
self.wait()
|
|
75
|
+
|
|
76
|
+
# Staggered transformation using LaggedStart with animate
|
|
77
|
+
self.play(
|
|
78
|
+
LaggedStart(
|
|
79
|
+
*[dot.animate.scale(1.5).set_color(YELLOW) for dot in dots],
|
|
80
|
+
lag_ratio=0.05
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
self.wait()
|
|
84
|
+
|
|
85
|
+
# Wave effect using AnimationGroup with rate_func
|
|
86
|
+
self.play(
|
|
87
|
+
LaggedStart(
|
|
88
|
+
*[dot.animate(rate_func=there_and_back).shift(UP * 0.5) for dot in dots],
|
|
89
|
+
lag_ratio=0.02,
|
|
90
|
+
run_time=2
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class AnimationComposition(Scene):
|
|
96
|
+
"""Demonstrates combining multiple animations."""
|
|
97
|
+
|
|
98
|
+
def construct(self):
|
|
99
|
+
# Create objects
|
|
100
|
+
circle = Circle(color=BLUE, fill_opacity=0.5)
|
|
101
|
+
label = Text("Circle", font_size=36).next_to(circle, DOWN)
|
|
102
|
+
|
|
103
|
+
# Group them
|
|
104
|
+
group = VGroup(circle, label)
|
|
105
|
+
|
|
106
|
+
# Animate together
|
|
107
|
+
self.play(
|
|
108
|
+
Create(circle),
|
|
109
|
+
Write(label),
|
|
110
|
+
run_time=2
|
|
111
|
+
)
|
|
112
|
+
self.wait()
|
|
113
|
+
|
|
114
|
+
# Sequential animations with Succession
|
|
115
|
+
square = Square(color=RED, fill_opacity=0.5).shift(RIGHT * 3)
|
|
116
|
+
square_label = Text("Square", font_size=36).next_to(square, DOWN)
|
|
117
|
+
|
|
118
|
+
self.play(
|
|
119
|
+
Succession(
|
|
120
|
+
group.animate.shift(LEFT * 2),
|
|
121
|
+
Create(square),
|
|
122
|
+
Write(square_label),
|
|
123
|
+
lag_ratio=0.5
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
self.wait()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class PathAnimations(Scene):
|
|
130
|
+
"""Demonstrates movement along paths."""
|
|
131
|
+
|
|
132
|
+
def construct(self):
|
|
133
|
+
# Create a path
|
|
134
|
+
path = VMobject()
|
|
135
|
+
path.set_points_smoothly([
|
|
136
|
+
LEFT * 3,
|
|
137
|
+
LEFT * 2 + UP * 2,
|
|
138
|
+
ORIGIN + UP,
|
|
139
|
+
RIGHT * 2 + UP * 2,
|
|
140
|
+
RIGHT * 3,
|
|
141
|
+
])
|
|
142
|
+
path.set_color(GREY)
|
|
143
|
+
|
|
144
|
+
# Create moving object
|
|
145
|
+
dot = Dot(color=RED, radius=0.2)
|
|
146
|
+
dot.move_to(path.get_start())
|
|
147
|
+
|
|
148
|
+
self.add(path)
|
|
149
|
+
self.play(Create(path))
|
|
150
|
+
|
|
151
|
+
# Move along path
|
|
152
|
+
self.play(MoveAlongPath(dot, path), run_time=3, rate_func=smooth)
|
|
153
|
+
|
|
154
|
+
self.wait()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class ColorTransitions(Scene):
|
|
158
|
+
"""Demonstrates color manipulation and gradients."""
|
|
159
|
+
|
|
160
|
+
def construct(self):
|
|
161
|
+
# Color gradient on shapes
|
|
162
|
+
squares = VGroup(*[
|
|
163
|
+
Square(side_length=0.8, fill_opacity=0.8)
|
|
164
|
+
for _ in range(7)
|
|
165
|
+
]).arrange(RIGHT, buff=0.2)
|
|
166
|
+
|
|
167
|
+
# Apply gradient colors
|
|
168
|
+
colors = [RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, PINK]
|
|
169
|
+
for square, color in zip(squares, colors):
|
|
170
|
+
square.set_fill(color)
|
|
171
|
+
square.set_stroke(WHITE, width=2)
|
|
172
|
+
|
|
173
|
+
self.play(LaggedStartMap(GrowFromCenter, squares, lag_ratio=0.1))
|
|
174
|
+
self.wait()
|
|
175
|
+
|
|
176
|
+
# Animate color change
|
|
177
|
+
self.play(
|
|
178
|
+
*[square.animate.set_fill(interpolate_color(BLUE, RED, i / 6))
|
|
179
|
+
for i, square in enumerate(squares)],
|
|
180
|
+
run_time=2
|
|
181
|
+
)
|
|
182
|
+
self.wait()
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class GroupOperations(Scene):
|
|
186
|
+
"""Demonstrates VGroup operations and arrangements."""
|
|
187
|
+
|
|
188
|
+
def construct(self):
|
|
189
|
+
# Create VGroup
|
|
190
|
+
shapes = VGroup(
|
|
191
|
+
Circle(color=RED),
|
|
192
|
+
Square(color=GREEN),
|
|
193
|
+
Triangle(color=BLUE),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Arrange horizontally
|
|
197
|
+
shapes.arrange(RIGHT, buff=1)
|
|
198
|
+
self.play(Create(shapes))
|
|
199
|
+
self.wait()
|
|
200
|
+
|
|
201
|
+
# Scale entire group
|
|
202
|
+
self.play(shapes.animate.scale(0.5))
|
|
203
|
+
self.wait()
|
|
204
|
+
|
|
205
|
+
# Arrange vertically
|
|
206
|
+
self.play(shapes.animate.arrange(DOWN, buff=0.5))
|
|
207
|
+
self.wait()
|
|
208
|
+
|
|
209
|
+
# Apply operation to all
|
|
210
|
+
self.play(shapes.animate.set_fill(YELLOW, opacity=0.5))
|
|
211
|
+
|
|
212
|
+
self.wait()
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Graph and Function Plotting Patterns for Manim Community
|
|
3
|
+
|
|
4
|
+
Demonstrates Axes, NumberPlane, function plotting, and coordinate systems.
|
|
5
|
+
Adapted from 3b1b patterns for ManimCE.
|
|
6
|
+
|
|
7
|
+
Run with: manim -pql graph_plotting.py SceneName
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from manim import *
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BasicAxes(Scene):
|
|
15
|
+
"""Basic axes setup and labeling."""
|
|
16
|
+
|
|
17
|
+
def construct(self):
|
|
18
|
+
# Create axes
|
|
19
|
+
axes = Axes(
|
|
20
|
+
x_range=[-3, 3, 1],
|
|
21
|
+
y_range=[-2, 2, 1],
|
|
22
|
+
x_length=8,
|
|
23
|
+
y_length=5,
|
|
24
|
+
axis_config={
|
|
25
|
+
"include_tip": True,
|
|
26
|
+
"include_numbers": True,
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Labels
|
|
31
|
+
x_label = axes.get_x_axis_label("x")
|
|
32
|
+
y_label = axes.get_y_axis_label("y")
|
|
33
|
+
|
|
34
|
+
self.play(Create(axes), Write(x_label), Write(y_label))
|
|
35
|
+
self.wait()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class FunctionPlotting(Scene):
|
|
39
|
+
"""Plotting functions on axes."""
|
|
40
|
+
|
|
41
|
+
def construct(self):
|
|
42
|
+
axes = Axes(
|
|
43
|
+
x_range=[-3, 3, 1],
|
|
44
|
+
y_range=[-1, 9, 2],
|
|
45
|
+
x_length=8,
|
|
46
|
+
y_length=5,
|
|
47
|
+
axis_config={"include_numbers": True},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Plot y = x^2
|
|
51
|
+
parabola = axes.plot(
|
|
52
|
+
lambda x: x ** 2,
|
|
53
|
+
color=BLUE,
|
|
54
|
+
x_range=[-3, 3]
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Label
|
|
58
|
+
label = MathTex(r"y = x^2", color=BLUE)
|
|
59
|
+
label.next_to(parabola, UR)
|
|
60
|
+
|
|
61
|
+
self.play(Create(axes))
|
|
62
|
+
self.play(Create(parabola), Write(label))
|
|
63
|
+
self.wait()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class MultipleFunctions(Scene):
|
|
67
|
+
"""Multiple functions on same axes."""
|
|
68
|
+
|
|
69
|
+
def construct(self):
|
|
70
|
+
axes = Axes(
|
|
71
|
+
x_range=[-2 * PI, 2 * PI, PI / 2],
|
|
72
|
+
y_range=[-1.5, 1.5, 0.5],
|
|
73
|
+
x_length=10,
|
|
74
|
+
y_length=4,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Plot sine and cosine
|
|
78
|
+
sine = axes.plot(np.sin, color=BLUE, x_range=[-2 * PI, 2 * PI])
|
|
79
|
+
cosine = axes.plot(np.cos, color=RED, x_range=[-2 * PI, 2 * PI])
|
|
80
|
+
|
|
81
|
+
# Labels
|
|
82
|
+
sin_label = MathTex(r"\sin(x)", color=BLUE).to_corner(UR)
|
|
83
|
+
cos_label = MathTex(r"\cos(x)", color=RED).next_to(sin_label, DOWN)
|
|
84
|
+
|
|
85
|
+
self.play(Create(axes))
|
|
86
|
+
self.play(Create(sine), Write(sin_label))
|
|
87
|
+
self.play(Create(cosine), Write(cos_label))
|
|
88
|
+
self.wait()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AreaUnderCurve(Scene):
|
|
92
|
+
"""Visualizing area under a curve (integration)."""
|
|
93
|
+
|
|
94
|
+
def construct(self):
|
|
95
|
+
axes = Axes(
|
|
96
|
+
x_range=[0, 5, 1],
|
|
97
|
+
y_range=[0, 10, 2],
|
|
98
|
+
x_length=8,
|
|
99
|
+
y_length=5,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Function
|
|
103
|
+
func = axes.plot(lambda x: 0.5 * x ** 2, color=BLUE, x_range=[0, 4])
|
|
104
|
+
|
|
105
|
+
# Area under curve from x=1 to x=3
|
|
106
|
+
area = axes.get_area(
|
|
107
|
+
func,
|
|
108
|
+
x_range=[1, 3],
|
|
109
|
+
color=BLUE,
|
|
110
|
+
opacity=0.3
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Integral notation
|
|
114
|
+
integral = MathTex(
|
|
115
|
+
r"\int_1^3 \frac{x^2}{2} \, dx",
|
|
116
|
+
font_size=48
|
|
117
|
+
).to_corner(UR)
|
|
118
|
+
|
|
119
|
+
self.play(Create(axes))
|
|
120
|
+
self.play(Create(func))
|
|
121
|
+
self.play(FadeIn(area))
|
|
122
|
+
self.play(Write(integral))
|
|
123
|
+
self.wait()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class NumberPlaneExample(Scene):
|
|
127
|
+
"""Using NumberPlane for coordinate grid."""
|
|
128
|
+
|
|
129
|
+
def construct(self):
|
|
130
|
+
# Create number plane
|
|
131
|
+
plane = NumberPlane(
|
|
132
|
+
x_range=[-7, 7, 1],
|
|
133
|
+
y_range=[-4, 4, 1],
|
|
134
|
+
background_line_style={
|
|
135
|
+
"stroke_color": BLUE_D,
|
|
136
|
+
"stroke_width": 1,
|
|
137
|
+
"stroke_opacity": 0.5,
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Plot a point
|
|
142
|
+
point = Dot(plane.c2p(2, 3), color=RED, radius=0.15)
|
|
143
|
+
point_label = MathTex("(2, 3)", color=RED).next_to(point, UR, buff=0.1)
|
|
144
|
+
|
|
145
|
+
# Vector from origin to point
|
|
146
|
+
vector = Arrow(
|
|
147
|
+
plane.c2p(0, 0),
|
|
148
|
+
plane.c2p(2, 3),
|
|
149
|
+
buff=0,
|
|
150
|
+
color=YELLOW
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
self.play(Create(plane))
|
|
154
|
+
self.play(GrowArrow(vector))
|
|
155
|
+
self.play(FadeIn(point), Write(point_label))
|
|
156
|
+
self.wait()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ParametricCurve(Scene):
|
|
160
|
+
"""Plotting parametric curves."""
|
|
161
|
+
|
|
162
|
+
def construct(self):
|
|
163
|
+
axes = Axes(
|
|
164
|
+
x_range=[-4, 4, 1],
|
|
165
|
+
y_range=[-4, 4, 1],
|
|
166
|
+
x_length=7,
|
|
167
|
+
y_length=7,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Parametric curve (circle)
|
|
171
|
+
circle = axes.plot_parametric_curve(
|
|
172
|
+
lambda t: np.array([2 * np.cos(t), 2 * np.sin(t), 0]),
|
|
173
|
+
t_range=[0, 2 * PI],
|
|
174
|
+
color=BLUE
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Lissajous curve
|
|
178
|
+
lissajous = axes.plot_parametric_curve(
|
|
179
|
+
lambda t: np.array([2 * np.sin(3 * t), 2 * np.sin(2 * t), 0]),
|
|
180
|
+
t_range=[0, 2 * PI],
|
|
181
|
+
color=RED
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
self.play(Create(axes))
|
|
185
|
+
self.play(Create(circle))
|
|
186
|
+
self.wait()
|
|
187
|
+
self.play(Transform(circle, lissajous))
|
|
188
|
+
self.wait()
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class TangentLine(Scene):
|
|
192
|
+
"""Showing tangent line to a curve."""
|
|
193
|
+
|
|
194
|
+
def construct(self):
|
|
195
|
+
axes = Axes(
|
|
196
|
+
x_range=[-1, 4, 1],
|
|
197
|
+
y_range=[-1, 10, 2],
|
|
198
|
+
x_length=8,
|
|
199
|
+
y_length=5,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Function y = x^2
|
|
203
|
+
func = axes.plot(lambda x: x ** 2, color=BLUE, x_range=[0, 3])
|
|
204
|
+
|
|
205
|
+
# Point of tangency at x = 2
|
|
206
|
+
x_val = 2
|
|
207
|
+
point = Dot(axes.c2p(x_val, x_val ** 2), color=RED)
|
|
208
|
+
|
|
209
|
+
# Tangent line: derivative of x^2 is 2x, at x=2 slope is 4
|
|
210
|
+
tangent = axes.plot(
|
|
211
|
+
lambda x: 4 * (x - 2) + 4, # Point-slope form
|
|
212
|
+
color=YELLOW,
|
|
213
|
+
x_range=[0.5, 3.5]
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Label
|
|
217
|
+
slope_label = MathTex(r"m = 2x = 4", color=YELLOW).to_corner(UR)
|
|
218
|
+
|
|
219
|
+
self.play(Create(axes))
|
|
220
|
+
self.play(Create(func))
|
|
221
|
+
self.play(FadeIn(point))
|
|
222
|
+
self.play(Create(tangent), Write(slope_label))
|
|
223
|
+
self.wait()
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class AnimatedGraph(Scene):
|
|
227
|
+
"""Animating a function parameter change."""
|
|
228
|
+
|
|
229
|
+
def construct(self):
|
|
230
|
+
axes = Axes(
|
|
231
|
+
x_range=[-3, 3, 1],
|
|
232
|
+
y_range=[-2, 2, 1],
|
|
233
|
+
x_length=8,
|
|
234
|
+
y_length=5,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Amplitude tracker
|
|
238
|
+
amplitude = ValueTracker(1)
|
|
239
|
+
|
|
240
|
+
# Graph that updates with amplitude
|
|
241
|
+
graph = always_redraw(
|
|
242
|
+
lambda: axes.plot(
|
|
243
|
+
lambda x: amplitude.get_value() * np.sin(x),
|
|
244
|
+
color=BLUE,
|
|
245
|
+
x_range=[-3, 3]
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# Amplitude display
|
|
250
|
+
amp_text = always_redraw(
|
|
251
|
+
lambda: MathTex(
|
|
252
|
+
f"A = {amplitude.get_value():.1f}"
|
|
253
|
+
).to_corner(UR)
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
self.add(axes, graph, amp_text)
|
|
257
|
+
|
|
258
|
+
# Animate amplitude change
|
|
259
|
+
self.play(amplitude.animate.set_value(2), run_time=2)
|
|
260
|
+
self.play(amplitude.animate.set_value(0.5), run_time=2)
|
|
261
|
+
self.play(amplitude.animate.set_value(1.5), run_time=1)
|
|
262
|
+
self.wait()
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class RiemannSum(Scene):
|
|
266
|
+
"""Visualizing Riemann sums for integration."""
|
|
267
|
+
|
|
268
|
+
def construct(self):
|
|
269
|
+
axes = Axes(
|
|
270
|
+
x_range=[0, 5, 1],
|
|
271
|
+
y_range=[0, 5, 1],
|
|
272
|
+
x_length=8,
|
|
273
|
+
y_length=5,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Function
|
|
277
|
+
func = axes.plot(lambda x: 0.2 * x ** 2, color=BLUE, x_range=[0, 4])
|
|
278
|
+
|
|
279
|
+
self.play(Create(axes), Create(func))
|
|
280
|
+
self.wait()
|
|
281
|
+
|
|
282
|
+
# Riemann rectangles
|
|
283
|
+
dx_values = [1, 0.5, 0.25]
|
|
284
|
+
|
|
285
|
+
for dx in dx_values:
|
|
286
|
+
rects = axes.get_riemann_rectangles(
|
|
287
|
+
func,
|
|
288
|
+
x_range=[1, 3],
|
|
289
|
+
dx=dx,
|
|
290
|
+
color=BLUE,
|
|
291
|
+
fill_opacity=0.5,
|
|
292
|
+
stroke_width=1,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if dx == 1:
|
|
296
|
+
self.play(Create(rects))
|
|
297
|
+
else:
|
|
298
|
+
self.play(Transform(rects, rects))
|
|
299
|
+
|
|
300
|
+
self.wait()
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class ImplicitFunction(Scene):
|
|
304
|
+
"""Plotting implicit functions (level curves)."""
|
|
305
|
+
|
|
306
|
+
def construct(self):
|
|
307
|
+
axes = Axes(
|
|
308
|
+
x_range=[-4, 4, 1],
|
|
309
|
+
y_range=[-4, 4, 1],
|
|
310
|
+
x_length=7,
|
|
311
|
+
y_length=7,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Circle x^2 + y^2 = 4 as parametric
|
|
315
|
+
circle = axes.plot_parametric_curve(
|
|
316
|
+
lambda t: np.array([2 * np.cos(t), 2 * np.sin(t), 0]),
|
|
317
|
+
t_range=[0, 2 * PI],
|
|
318
|
+
color=BLUE
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Equation label
|
|
322
|
+
equation = MathTex(r"x^2 + y^2 = 4", color=BLUE).to_corner(UR)
|
|
323
|
+
|
|
324
|
+
self.play(Create(axes))
|
|
325
|
+
self.play(Create(circle), Write(equation))
|
|
326
|
+
self.wait()
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
class CoordinateLabeling(Scene):
|
|
330
|
+
"""Advanced coordinate labeling techniques."""
|
|
331
|
+
|
|
332
|
+
def construct(self):
|
|
333
|
+
axes = Axes(
|
|
334
|
+
x_range=[-1, 5, 1],
|
|
335
|
+
y_range=[-1, 5, 1],
|
|
336
|
+
x_length=7,
|
|
337
|
+
y_length=7,
|
|
338
|
+
axis_config={"include_numbers": True},
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# Function
|
|
342
|
+
func = axes.plot(lambda x: np.sqrt(x), color=BLUE, x_range=[0, 4])
|
|
343
|
+
|
|
344
|
+
# Highlight a specific point
|
|
345
|
+
x_val = 2
|
|
346
|
+
y_val = np.sqrt(2)
|
|
347
|
+
|
|
348
|
+
point = Dot(axes.c2p(x_val, y_val), color=RED)
|
|
349
|
+
|
|
350
|
+
# Dashed lines to axes
|
|
351
|
+
h_line = DashedLine(
|
|
352
|
+
axes.c2p(0, y_val),
|
|
353
|
+
axes.c2p(x_val, y_val),
|
|
354
|
+
color=GREY
|
|
355
|
+
)
|
|
356
|
+
v_line = DashedLine(
|
|
357
|
+
axes.c2p(x_val, 0),
|
|
358
|
+
axes.c2p(x_val, y_val),
|
|
359
|
+
color=GREY
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
# Labels
|
|
363
|
+
x_label = MathTex("2").next_to(axes.c2p(x_val, 0), DOWN)
|
|
364
|
+
y_label = MathTex(r"\sqrt{2}").next_to(axes.c2p(0, y_val), LEFT)
|
|
365
|
+
|
|
366
|
+
self.play(Create(axes))
|
|
367
|
+
self.play(Create(func))
|
|
368
|
+
self.play(Create(v_line), Create(h_line))
|
|
369
|
+
self.play(FadeIn(point), Write(x_label), Write(y_label))
|
|
370
|
+
self.wait()
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class PolarPlot(Scene):
|
|
374
|
+
"""Plotting in polar coordinates."""
|
|
375
|
+
|
|
376
|
+
def construct(self):
|
|
377
|
+
# Polar axes
|
|
378
|
+
polar_plane = PolarPlane(
|
|
379
|
+
radius_max=3,
|
|
380
|
+
size=6,
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
# Polar curve: r = 1 + sin(theta) (cardioid)
|
|
384
|
+
cardioid = polar_plane.plot_polar_graph(
|
|
385
|
+
lambda theta: 1 + np.sin(theta),
|
|
386
|
+
theta_range=[0, 2 * PI],
|
|
387
|
+
color=BLUE
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
# Rose curve: r = 2*cos(3*theta)
|
|
391
|
+
rose = polar_plane.plot_polar_graph(
|
|
392
|
+
lambda theta: 2 * np.cos(3 * theta),
|
|
393
|
+
theta_range=[0, PI],
|
|
394
|
+
color=RED
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
self.play(Create(polar_plane))
|
|
398
|
+
self.play(Create(cardioid))
|
|
399
|
+
self.wait()
|
|
400
|
+
self.play(Transform(cardioid, rose))
|
|
401
|
+
self.wait()
|