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,172 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Lorenz Attractor - Converted from 3b1b ManimGL to ManimCE
|
|
3
|
+
|
|
4
|
+
Original: videos/_2024/manim_demo/lorenz.py
|
|
5
|
+
This demonstrates a chaotic system visualization with 3D curves and tracing dots.
|
|
6
|
+
|
|
7
|
+
Run with: manim -pql lorenz_attractor.py LorenzAttractor
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from manim import *
|
|
11
|
+
from scipy.integrate import solve_ivp
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def lorenz_system(t, state, sigma=10, rho=28, beta=8 / 3):
|
|
16
|
+
"""The Lorenz system of differential equations."""
|
|
17
|
+
x, y, z = state
|
|
18
|
+
dxdt = sigma * (y - x)
|
|
19
|
+
dydt = x * (rho - z) - y
|
|
20
|
+
dzdt = x * y - beta * z
|
|
21
|
+
return [dxdt, dydt, dzdt]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def ode_solution_points(function, state0, time, dt=0.01):
|
|
25
|
+
"""Solve ODE and return solution points."""
|
|
26
|
+
solution = solve_ivp(
|
|
27
|
+
function,
|
|
28
|
+
t_span=(0, time),
|
|
29
|
+
y0=state0,
|
|
30
|
+
t_eval=np.arange(0, time, dt)
|
|
31
|
+
)
|
|
32
|
+
return solution.y.T
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class LorenzAttractor(ThreeDScene):
|
|
36
|
+
"""
|
|
37
|
+
Visualization of the Lorenz attractor - a classic chaotic system.
|
|
38
|
+
|
|
39
|
+
Shows multiple trajectories starting from nearly identical initial conditions
|
|
40
|
+
that diverge chaotically over time.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def construct(self):
|
|
44
|
+
# Set up 3D axes
|
|
45
|
+
axes = ThreeDAxes(
|
|
46
|
+
x_range=(-50, 50, 10),
|
|
47
|
+
y_range=(-50, 50, 10),
|
|
48
|
+
z_range=(0, 50, 10),
|
|
49
|
+
x_length=12,
|
|
50
|
+
y_length=12,
|
|
51
|
+
z_length=6,
|
|
52
|
+
)
|
|
53
|
+
axes.center()
|
|
54
|
+
|
|
55
|
+
# Set camera orientation
|
|
56
|
+
self.set_camera_orientation(phi=76 * DEGREES, theta=43 * DEGREES)
|
|
57
|
+
|
|
58
|
+
self.add(axes)
|
|
59
|
+
|
|
60
|
+
# Add the equations (fixed to screen)
|
|
61
|
+
equations = MathTex(
|
|
62
|
+
r"\frac{dx}{dt} &= \sigma(y-x) \\",
|
|
63
|
+
r"\frac{dy}{dt} &= x(\rho-z)-y \\",
|
|
64
|
+
r"\frac{dz}{dt} &= xy-\beta z",
|
|
65
|
+
font_size=30
|
|
66
|
+
)
|
|
67
|
+
equations.to_corner(UL)
|
|
68
|
+
self.add_fixed_in_frame_mobjects(equations)
|
|
69
|
+
self.play(Write(equations))
|
|
70
|
+
|
|
71
|
+
# Compute a set of solutions with slightly different initial conditions
|
|
72
|
+
epsilon = 1e-5
|
|
73
|
+
evolution_time = 20 # Reduced for faster rendering
|
|
74
|
+
n_points = 5 # Reduced for performance
|
|
75
|
+
|
|
76
|
+
states = [
|
|
77
|
+
[10, 10, 10 + n * epsilon]
|
|
78
|
+
for n in range(n_points)
|
|
79
|
+
]
|
|
80
|
+
colors = color_gradient([BLUE_E, BLUE_A], len(states))
|
|
81
|
+
|
|
82
|
+
# Create curves from ODE solutions
|
|
83
|
+
curves = VGroup()
|
|
84
|
+
for state, color in zip(states, colors):
|
|
85
|
+
points = ode_solution_points(lorenz_system, state, evolution_time)
|
|
86
|
+
# Scale points to fit axes
|
|
87
|
+
scaled_points = [axes.c2p(p[0], p[1], p[2]) for p in points]
|
|
88
|
+
curve = VMobject()
|
|
89
|
+
curve.set_points_smoothly(scaled_points)
|
|
90
|
+
curve.set_stroke(color, width=2, opacity=0.8)
|
|
91
|
+
curves.add(curve)
|
|
92
|
+
|
|
93
|
+
# Create dots that will trace the curves
|
|
94
|
+
dots = VGroup(*[
|
|
95
|
+
Dot3D(color=color, radius=0.15)
|
|
96
|
+
for color in colors
|
|
97
|
+
])
|
|
98
|
+
|
|
99
|
+
# Position dots at start of curves
|
|
100
|
+
for dot, curve in zip(dots, curves):
|
|
101
|
+
dot.move_to(curve.get_start())
|
|
102
|
+
|
|
103
|
+
self.add(dots)
|
|
104
|
+
|
|
105
|
+
# Start ambient camera rotation
|
|
106
|
+
self.begin_ambient_camera_rotation(rate=0.1)
|
|
107
|
+
|
|
108
|
+
# Animate curves being drawn with dots following
|
|
109
|
+
self.play(
|
|
110
|
+
*[Create(curve, rate_func=linear) for curve in curves],
|
|
111
|
+
*[MoveAlongPath(dot, curve, rate_func=linear) for dot, curve in zip(dots, curves)],
|
|
112
|
+
run_time=evolution_time,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
self.wait(2)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class LorenzAttractorSimple(ThreeDScene):
|
|
119
|
+
"""
|
|
120
|
+
Simplified version with just one trajectory and traced path.
|
|
121
|
+
Better for understanding the basic pattern.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def construct(self):
|
|
125
|
+
# Set up axes
|
|
126
|
+
axes = ThreeDAxes(
|
|
127
|
+
x_range=(-50, 50, 10),
|
|
128
|
+
y_range=(-50, 50, 10),
|
|
129
|
+
z_range=(0, 50, 10),
|
|
130
|
+
x_length=10,
|
|
131
|
+
y_length=10,
|
|
132
|
+
z_length=5,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
self.set_camera_orientation(phi=70 * DEGREES, theta=45 * DEGREES)
|
|
136
|
+
self.add(axes)
|
|
137
|
+
|
|
138
|
+
# Compute single trajectory
|
|
139
|
+
evolution_time = 15
|
|
140
|
+
points = ode_solution_points(lorenz_system, [10, 10, 10], evolution_time)
|
|
141
|
+
scaled_points = [axes.c2p(p[0], p[1], p[2]) for p in points]
|
|
142
|
+
|
|
143
|
+
# Create curve
|
|
144
|
+
curve = VMobject()
|
|
145
|
+
curve.set_points_smoothly(scaled_points)
|
|
146
|
+
curve.set_stroke(BLUE, width=2)
|
|
147
|
+
|
|
148
|
+
# Create moving dot with traced path
|
|
149
|
+
dot = Dot3D(color=RED, radius=0.2)
|
|
150
|
+
dot.move_to(curve.get_start())
|
|
151
|
+
|
|
152
|
+
# Traced path follows the dot
|
|
153
|
+
traced_path = TracedPath(
|
|
154
|
+
dot.get_center,
|
|
155
|
+
stroke_color=YELLOW,
|
|
156
|
+
stroke_width=3,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
self.add(traced_path, dot)
|
|
160
|
+
|
|
161
|
+
# Title
|
|
162
|
+
title = Text("Lorenz Attractor", font_size=36)
|
|
163
|
+
title.to_corner(UL)
|
|
164
|
+
self.add_fixed_in_frame_mobjects(title)
|
|
165
|
+
|
|
166
|
+
# Animate
|
|
167
|
+
self.begin_ambient_camera_rotation(rate=0.15)
|
|
168
|
+
self.play(
|
|
169
|
+
MoveAlongPath(dot, curve, rate_func=linear),
|
|
170
|
+
run_time=evolution_time,
|
|
171
|
+
)
|
|
172
|
+
self.wait(2)
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Mathematical Visualization Patterns for Manim Community
|
|
3
|
+
|
|
4
|
+
Demonstrates LaTeX rendering, equation animations, and color-coded math.
|
|
5
|
+
Adapted from 3b1b patterns for ManimCE compatibility.
|
|
6
|
+
|
|
7
|
+
Run with: manim -pql math_visualization.py SceneName
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from manim import *
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ColorCodedEquation(Scene):
|
|
14
|
+
"""Demonstrates color-coding for syntax highlighting in equations."""
|
|
15
|
+
|
|
16
|
+
def construct(self):
|
|
17
|
+
# Method 1: Use set_color_by_tex after creation (safer approach)
|
|
18
|
+
equation = MathTex(
|
|
19
|
+
r"\vec{v}_1", r"=", r"\begin{bmatrix} 1 \\ \lambda_1 \end{bmatrix}"
|
|
20
|
+
)
|
|
21
|
+
equation.scale(1.5)
|
|
22
|
+
|
|
23
|
+
# Color specific parts
|
|
24
|
+
equation[0].set_color(TEAL) # \vec{v}_1
|
|
25
|
+
|
|
26
|
+
self.play(Write(equation))
|
|
27
|
+
self.wait()
|
|
28
|
+
|
|
29
|
+
# Second equation with multiple colored parts
|
|
30
|
+
equation2 = MathTex(r"A", r"\vec{v}_1", r"=", r"\lambda_1", r"\vec{v}_1")
|
|
31
|
+
equation2.scale(1.5)
|
|
32
|
+
equation2[0].set_color(RED) # A
|
|
33
|
+
equation2[1].set_color(TEAL) # first \vec{v}_1
|
|
34
|
+
equation2[3].set_color(YELLOW) # \lambda_1
|
|
35
|
+
equation2[4].set_color(TEAL) # second \vec{v}_1
|
|
36
|
+
|
|
37
|
+
self.play(TransformMatchingTex(equation, equation2))
|
|
38
|
+
self.wait()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class EquationDerivation(Scene):
|
|
42
|
+
"""Shows step-by-step equation derivation with highlighting."""
|
|
43
|
+
|
|
44
|
+
def construct(self):
|
|
45
|
+
# Starting equation
|
|
46
|
+
eq1 = MathTex(r"x^2 + 5x + 6 = 0")
|
|
47
|
+
eq1.to_edge(UP)
|
|
48
|
+
|
|
49
|
+
self.play(Write(eq1))
|
|
50
|
+
self.wait()
|
|
51
|
+
|
|
52
|
+
# Factor step
|
|
53
|
+
eq2 = MathTex(r"(x + 2)(x + 3) = 0")
|
|
54
|
+
eq2.next_to(eq1, DOWN, buff=0.8)
|
|
55
|
+
|
|
56
|
+
self.play(
|
|
57
|
+
TransformFromCopy(eq1, eq2),
|
|
58
|
+
run_time=1.5
|
|
59
|
+
)
|
|
60
|
+
self.wait()
|
|
61
|
+
|
|
62
|
+
# Solutions
|
|
63
|
+
eq3 = MathTex(r"x = -2", color=BLUE)
|
|
64
|
+
eq4 = MathTex(r"x = -3", color=GREEN)
|
|
65
|
+
solutions = VGroup(eq3, eq4).arrange(RIGHT, buff=1)
|
|
66
|
+
solutions.next_to(eq2, DOWN, buff=0.8)
|
|
67
|
+
|
|
68
|
+
self.play(
|
|
69
|
+
LaggedStart(
|
|
70
|
+
Write(eq3),
|
|
71
|
+
Write(eq4),
|
|
72
|
+
lag_ratio=0.3
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Highlight solutions
|
|
77
|
+
boxes = VGroup(
|
|
78
|
+
SurroundingRectangle(eq3, color=BLUE),
|
|
79
|
+
SurroundingRectangle(eq4, color=GREEN),
|
|
80
|
+
)
|
|
81
|
+
self.play(Create(boxes))
|
|
82
|
+
self.wait()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class MatrixTransformation(Scene):
|
|
86
|
+
"""Demonstrates matrix notation and transformations."""
|
|
87
|
+
|
|
88
|
+
def construct(self):
|
|
89
|
+
# Matrix definition
|
|
90
|
+
matrix = MathTex(
|
|
91
|
+
r"A = \begin{bmatrix} 2 & 1 \\ 1 & 3 \end{bmatrix}"
|
|
92
|
+
).scale(1.2)
|
|
93
|
+
|
|
94
|
+
self.play(Write(matrix))
|
|
95
|
+
self.wait()
|
|
96
|
+
|
|
97
|
+
# Move to side
|
|
98
|
+
self.play(matrix.animate.to_edge(LEFT))
|
|
99
|
+
|
|
100
|
+
# Show transformation
|
|
101
|
+
vector = MathTex(
|
|
102
|
+
r"\vec{x} = \begin{bmatrix} 1 \\ 1 \end{bmatrix}",
|
|
103
|
+
color=YELLOW
|
|
104
|
+
)
|
|
105
|
+
vector.next_to(matrix, RIGHT, buff=1)
|
|
106
|
+
|
|
107
|
+
self.play(Write(vector))
|
|
108
|
+
self.wait()
|
|
109
|
+
|
|
110
|
+
# Result
|
|
111
|
+
result = MathTex(
|
|
112
|
+
r"A\vec{x} = \begin{bmatrix} 3 \\ 4 \end{bmatrix}",
|
|
113
|
+
tex_to_color_map={r"\vec{x}": YELLOW}
|
|
114
|
+
)
|
|
115
|
+
result.next_to(vector, RIGHT, buff=1)
|
|
116
|
+
|
|
117
|
+
arrow = Arrow(vector.get_right(), result.get_left(), buff=0.2)
|
|
118
|
+
|
|
119
|
+
self.play(GrowArrow(arrow), Write(result))
|
|
120
|
+
self.wait()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class IntegralVisualization(Scene):
|
|
124
|
+
"""Shows integral notation with visual meaning."""
|
|
125
|
+
|
|
126
|
+
def construct(self):
|
|
127
|
+
# Integral expression
|
|
128
|
+
integral = MathTex(
|
|
129
|
+
r"\int_0^1 x^2 \, dx = \frac{1}{3}",
|
|
130
|
+
font_size=64
|
|
131
|
+
)
|
|
132
|
+
integral.to_edge(UP)
|
|
133
|
+
|
|
134
|
+
self.play(Write(integral))
|
|
135
|
+
self.wait()
|
|
136
|
+
|
|
137
|
+
# Create axes
|
|
138
|
+
axes = Axes(
|
|
139
|
+
x_range=[0, 1.2, 0.5],
|
|
140
|
+
y_range=[0, 1.2, 0.5],
|
|
141
|
+
x_length=5,
|
|
142
|
+
y_length=3,
|
|
143
|
+
axis_config={"include_tip": True},
|
|
144
|
+
)
|
|
145
|
+
axes.shift(DOWN)
|
|
146
|
+
|
|
147
|
+
# Create graph
|
|
148
|
+
graph = axes.plot(lambda x: x**2, x_range=[0, 1], color=BLUE)
|
|
149
|
+
|
|
150
|
+
# Create area under curve
|
|
151
|
+
area = axes.get_area(graph, x_range=[0, 1], color=BLUE, opacity=0.3)
|
|
152
|
+
|
|
153
|
+
self.play(Create(axes))
|
|
154
|
+
self.play(Create(graph))
|
|
155
|
+
self.play(FadeIn(area))
|
|
156
|
+
self.wait()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class SummationNotation(Scene):
|
|
160
|
+
"""Demonstrates summation and series notation."""
|
|
161
|
+
|
|
162
|
+
def construct(self):
|
|
163
|
+
# Summation formula
|
|
164
|
+
formula = MathTex(
|
|
165
|
+
r"\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}",
|
|
166
|
+
font_size=64
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
self.play(Write(formula))
|
|
170
|
+
self.wait()
|
|
171
|
+
|
|
172
|
+
# Show first few terms
|
|
173
|
+
terms = MathTex(
|
|
174
|
+
r"= 1 + \frac{1}{4} + \frac{1}{9} + \frac{1}{16} + \cdots",
|
|
175
|
+
font_size=48
|
|
176
|
+
)
|
|
177
|
+
terms.next_to(formula, DOWN, buff=0.8)
|
|
178
|
+
|
|
179
|
+
self.play(Write(terms))
|
|
180
|
+
self.wait()
|
|
181
|
+
|
|
182
|
+
# Create surrounding box around result
|
|
183
|
+
box = SurroundingRectangle(formula, color=YELLOW, buff=0.2)
|
|
184
|
+
self.play(Create(box))
|
|
185
|
+
self.wait()
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class FunctionNotation(Scene):
|
|
189
|
+
"""Shows function definition and evaluation."""
|
|
190
|
+
|
|
191
|
+
def construct(self):
|
|
192
|
+
# Function definition
|
|
193
|
+
f_def = MathTex(r"f(x) = x^2 + 2x + 1", font_size=56)
|
|
194
|
+
f_def.to_edge(UP)
|
|
195
|
+
|
|
196
|
+
self.play(Write(f_def))
|
|
197
|
+
self.wait()
|
|
198
|
+
|
|
199
|
+
# Evaluation at x=3
|
|
200
|
+
eval_step1 = MathTex(r"f(3) = 3^2 + 2(3) + 1", font_size=48)
|
|
201
|
+
eval_step2 = MathTex(r"f(3) = 9 + 6 + 1", font_size=48)
|
|
202
|
+
eval_step3 = MathTex(r"f(3) = 16", font_size=48, color=GREEN)
|
|
203
|
+
|
|
204
|
+
steps = VGroup(eval_step1, eval_step2, eval_step3)
|
|
205
|
+
steps.arrange(DOWN, buff=0.5)
|
|
206
|
+
steps.next_to(f_def, DOWN, buff=1)
|
|
207
|
+
|
|
208
|
+
for step in steps:
|
|
209
|
+
self.play(Write(step))
|
|
210
|
+
self.wait(0.5)
|
|
211
|
+
|
|
212
|
+
# Box the answer
|
|
213
|
+
box = SurroundingRectangle(eval_step3, color=GREEN)
|
|
214
|
+
self.play(Create(box))
|
|
215
|
+
self.wait()
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class LimitNotation(Scene):
|
|
219
|
+
"""Demonstrates limit notation and evaluation."""
|
|
220
|
+
|
|
221
|
+
def construct(self):
|
|
222
|
+
# Limit expression
|
|
223
|
+
limit = MathTex(
|
|
224
|
+
r"\lim_{x \to 0} \frac{\sin x}{x} = 1",
|
|
225
|
+
font_size=64
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
self.play(Write(limit))
|
|
229
|
+
self.wait()
|
|
230
|
+
|
|
231
|
+
# Show approaching behavior
|
|
232
|
+
approaching = MathTex(
|
|
233
|
+
r"x \to 0: \quad",
|
|
234
|
+
r"\frac{\sin(0.1)}{0.1} \approx 0.998",
|
|
235
|
+
font_size=40
|
|
236
|
+
)
|
|
237
|
+
approaching.next_to(limit, DOWN, buff=1)
|
|
238
|
+
|
|
239
|
+
self.play(Write(approaching))
|
|
240
|
+
self.wait()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class DerivativeChainRule(Scene):
|
|
244
|
+
"""Shows the chain rule for derivatives."""
|
|
245
|
+
|
|
246
|
+
def construct(self):
|
|
247
|
+
title = Text("Chain Rule", font_size=48, color=BLUE)
|
|
248
|
+
title.to_edge(UP)
|
|
249
|
+
|
|
250
|
+
# Chain rule formula
|
|
251
|
+
rule = MathTex(
|
|
252
|
+
r"\frac{d}{dx}[f(g(x))] = f'(g(x)) \cdot g'(x)",
|
|
253
|
+
font_size=48
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Example
|
|
257
|
+
example_title = Text("Example:", font_size=36)
|
|
258
|
+
example = MathTex(
|
|
259
|
+
r"\frac{d}{dx}[\sin(x^2)] = \cos(x^2) \cdot 2x",
|
|
260
|
+
tex_to_color_map={
|
|
261
|
+
r"\sin": BLUE,
|
|
262
|
+
r"\cos": BLUE,
|
|
263
|
+
r"x^2": YELLOW,
|
|
264
|
+
r"2x": YELLOW,
|
|
265
|
+
},
|
|
266
|
+
font_size=44
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
content = VGroup(rule, example_title, example)
|
|
270
|
+
content.arrange(DOWN, buff=0.8)
|
|
271
|
+
|
|
272
|
+
self.play(Write(title))
|
|
273
|
+
self.play(Write(rule))
|
|
274
|
+
self.wait()
|
|
275
|
+
self.play(Write(example_title))
|
|
276
|
+
self.play(Write(example))
|
|
277
|
+
self.wait()
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class TexHighlighting(Scene):
|
|
281
|
+
"""Advanced tex highlighting techniques."""
|
|
282
|
+
|
|
283
|
+
def construct(self):
|
|
284
|
+
# Create equation with substrings to highlight
|
|
285
|
+
equation = MathTex(
|
|
286
|
+
r"E", r"=", r"m", r"c^2",
|
|
287
|
+
font_size=96
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
self.play(Write(equation))
|
|
291
|
+
self.wait()
|
|
292
|
+
|
|
293
|
+
# Highlight individual parts
|
|
294
|
+
self.play(equation[0].animate.set_color(YELLOW)) # E
|
|
295
|
+
self.wait(0.3)
|
|
296
|
+
self.play(equation[2].animate.set_color(BLUE)) # m
|
|
297
|
+
self.wait(0.3)
|
|
298
|
+
self.play(equation[3].animate.set_color(RED)) # c^2
|
|
299
|
+
self.wait()
|
|
300
|
+
|
|
301
|
+
# Add labels
|
|
302
|
+
e_label = Text("Energy", font_size=24, color=YELLOW)
|
|
303
|
+
m_label = Text("Mass", font_size=24, color=BLUE)
|
|
304
|
+
c_label = Text("Speed of Light", font_size=24, color=RED)
|
|
305
|
+
|
|
306
|
+
e_label.next_to(equation[0], UP)
|
|
307
|
+
m_label.next_to(equation[2], DOWN)
|
|
308
|
+
c_label.next_to(equation[3], UP)
|
|
309
|
+
|
|
310
|
+
self.play(
|
|
311
|
+
FadeIn(e_label, shift=DOWN * 0.3),
|
|
312
|
+
FadeIn(m_label, shift=UP * 0.3),
|
|
313
|
+
FadeIn(c_label, shift=DOWN * 0.3),
|
|
314
|
+
)
|
|
315
|
+
self.wait()
|