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.
Files changed (64) hide show
  1. package/README.md +104 -0
  2. package/dist/demo.mp4 +0 -0
  3. package/dist/index.js +65 -0
  4. package/dist/mcp-app.html +142 -0
  5. package/dist/server.js +1492 -0
  6. package/package.json +67 -0
  7. package/references/composer/SKILL.md +154 -0
  8. package/references/composer/references/3b1b-series-patterns.md +217 -0
  9. package/references/composer/references/domain-planning-guides/calculus-planning.md +188 -0
  10. package/references/composer/references/domain-planning-guides/linear-algebra-planning.md +169 -0
  11. package/references/composer/references/domain-planning-guides/ml-planning.md +286 -0
  12. package/references/composer/references/domain-planning-guides/number-theory-planning.md +187 -0
  13. package/references/composer/references/domain-planning-guides/physics-planning.md +249 -0
  14. package/references/composer/references/domain-planning-guides/probability-planning.md +200 -0
  15. package/references/composer/references/mathematical-storytelling.md +359 -0
  16. package/references/composer/references/narrative-patterns.md +221 -0
  17. package/references/composer/references/opening-patterns.md +284 -0
  18. package/references/composer/references/pacing-guide.md +289 -0
  19. package/references/composer/references/scene-archetypes.md +534 -0
  20. package/references/composer/references/scene-examples.md +379 -0
  21. package/references/composer/references/visual-techniques.md +480 -0
  22. package/references/composer/templates/scenes-template.md +147 -0
  23. package/references/manimce/SKILL.md +166 -0
  24. package/references/manimce/examples/3d_visualization.py +373 -0
  25. package/references/manimce/examples/basic_animations.py +212 -0
  26. package/references/manimce/examples/graph_plotting.py +401 -0
  27. package/references/manimce/examples/lorenz_attractor.py +172 -0
  28. package/references/manimce/examples/math_visualization.py +315 -0
  29. package/references/manimce/examples/updater_patterns.py +369 -0
  30. package/references/manimce/rules/3b1b-translation.md +594 -0
  31. package/references/manimce/rules/3d.md +254 -0
  32. package/references/manimce/rules/advanced-animations.md +594 -0
  33. package/references/manimce/rules/animation-groups.md +212 -0
  34. package/references/manimce/rules/animations.md +128 -0
  35. package/references/manimce/rules/api-pitfalls.md +89 -0
  36. package/references/manimce/rules/axes.md +214 -0
  37. package/references/manimce/rules/camera.md +208 -0
  38. package/references/manimce/rules/cli.md +232 -0
  39. package/references/manimce/rules/color-conventions.md +444 -0
  40. package/references/manimce/rules/colors.md +199 -0
  41. package/references/manimce/rules/config.md +264 -0
  42. package/references/manimce/rules/creation-animations.md +158 -0
  43. package/references/manimce/rules/graphing.md +233 -0
  44. package/references/manimce/rules/grouping.md +220 -0
  45. package/references/manimce/rules/latex.md +202 -0
  46. package/references/manimce/rules/lines.md +241 -0
  47. package/references/manimce/rules/long-form-video.md +552 -0
  48. package/references/manimce/rules/mathematical-domains.md +689 -0
  49. package/references/manimce/rules/mobjects.md +116 -0
  50. package/references/manimce/rules/multi-scene-composition.md +112 -0
  51. package/references/manimce/rules/pedagogy.md +532 -0
  52. package/references/manimce/rules/physics-simulations.md +610 -0
  53. package/references/manimce/rules/positioning.md +211 -0
  54. package/references/manimce/rules/scenes.md +121 -0
  55. package/references/manimce/rules/shapes.md +300 -0
  56. package/references/manimce/rules/styling.md +177 -0
  57. package/references/manimce/rules/text-animations.md +222 -0
  58. package/references/manimce/rules/text.md +189 -0
  59. package/references/manimce/rules/timing.md +227 -0
  60. package/references/manimce/rules/transform-animations.md +157 -0
  61. package/references/manimce/rules/updaters.md +226 -0
  62. package/references/manimce/templates/basic_scene.py +64 -0
  63. package/references/manimce/templates/camera_scene.py +100 -0
  64. package/references/manimce/templates/threed_scene.py +138 -0
@@ -0,0 +1,594 @@
1
+ ---
2
+ name: 3b1b-translation
3
+ description: Comprehensive guide for translating ManimGL (3b1b video code) to ManimCE, with examples from all 407 video files
4
+ metadata:
5
+ tags: manimgl, manimce, translation, migration, porting, conversion, 3b1b, ShowCreation, CONFIG, InteractiveScene
6
+ ---
7
+
8
+ # Translating ManimGL to ManimCE
9
+
10
+ This guide covers every major difference between the ManimGL code used in 3Blue1Brown's video repository and ManimCE (Manim Community Edition). The patterns come from analyzing 407 Python files across the `_2015/` through `_2026/` directories.
11
+
12
+ ## Animation Name Changes
13
+
14
+ ### ShowCreation to Create
15
+
16
+ The single most common translation. Every 3b1b file uses `ShowCreation`.
17
+
18
+ ```python
19
+ # ManimGL (3b1b)
20
+ self.play(ShowCreation(circle))
21
+ self.play(ShowCreation(plane, lag_ratio=0.01, run_time=3))
22
+ self.play(ShowCreation(rect))
23
+
24
+ # ManimCE
25
+ self.play(Create(circle))
26
+ self.play(Create(plane, lag_ratio=0.01, run_time=3))
27
+ self.play(Create(rect))
28
+ ```
29
+
30
+ ### Other Renamed Animations
31
+
32
+ ```python
33
+ # ManimGL # ManimCE
34
+ ShowCreation(mob) Create(mob)
35
+ ShowCreation(mob, lag_ratio=0.5) Create(mob, lag_ratio=0.5)
36
+ # Note: Write() works the same in both for text/equations
37
+
38
+ # These are the same in both:
39
+ # FadeIn, FadeOut, Write, GrowArrow, GrowFromCenter, Transform,
40
+ # ReplacementTransform, DrawBorderThenFill, Rotate, MoveToTarget,
41
+ # LaggedStartMap, LaggedStart, Succession, AnimationGroup
42
+ ```
43
+
44
+ ## Scene Classes
45
+
46
+ ### InteractiveScene to Scene
47
+
48
+ 3b1b's base class for most scenes is `InteractiveScene`. ManimCE uses `Scene`.
49
+
50
+ ```python
51
+ # ManimGL (3b1b)
52
+ class MyScene(InteractiveScene):
53
+ def construct(self):
54
+ ...
55
+
56
+ # ManimCE
57
+ class MyScene(Scene):
58
+ def construct(self):
59
+ ...
60
+ ```
61
+
62
+ ### PiCreatureScene / TeacherStudentsScene
63
+
64
+ These exist in 3b1b's custom directory (`custom/characters/`) and are not part of ManimCE. You can create similar patterns manually or use community plugins.
65
+
66
+ ```python
67
+ # ManimGL (3b1b)
68
+ class AskAboutPosition(TeacherStudentsScene):
69
+ def construct(self):
70
+ self.teacher_says("Think about this...")
71
+ self.student_says("Oh, I see!")
72
+
73
+ # ManimCE: No direct equivalent. Use plain Scene with custom mobjects.
74
+ class AskAboutPosition(Scene):
75
+ def construct(self):
76
+ # Create speech bubbles manually
77
+ teacher_text = Text("Think about this...", font_size=28)
78
+ bubble = SurroundingRectangle(teacher_text, buff=0.3, corner_radius=0.2)
79
+ self.play(Create(bubble), Write(teacher_text))
80
+ self.wait()
81
+ ```
82
+
83
+ ## CONFIG Dict to Class Attributes / __init__ Parameters
84
+
85
+ This is pervasive -- nearly every 3b1b class uses the CONFIG pattern.
86
+
87
+ ```python
88
+ # ManimGL (3b1b) -- CONFIG dict pattern
89
+ class Pendulum(VGroup):
90
+ CONFIG = {
91
+ "length": 3,
92
+ "gravity": 9.8,
93
+ "weight_diameter": 0.5,
94
+ "initial_theta": 0.3,
95
+ "omega": 0,
96
+ "damping": 0.1,
97
+ "top_point": 2 * UP,
98
+ "n_steps_per_frame": 100,
99
+ }
100
+
101
+ def __init__(self, **kwargs):
102
+ super().__init__(**kwargs)
103
+ # self.length, self.gravity etc. are auto-set from CONFIG
104
+
105
+ # ManimCE -- use __init__ parameters
106
+ class Pendulum(VGroup):
107
+ def __init__(
108
+ self,
109
+ length=3,
110
+ gravity=9.8,
111
+ weight_diameter=0.5,
112
+ initial_theta=0.3,
113
+ omega=0,
114
+ damping=0.1,
115
+ top_point=2 * UP,
116
+ n_steps_per_frame=100,
117
+ **kwargs,
118
+ ):
119
+ super().__init__(**kwargs)
120
+ self.length = length
121
+ self.gravity = gravity
122
+ self.weight_diameter = weight_diameter
123
+ self.initial_theta = initial_theta
124
+ self.omega = omega
125
+ self.damping = damping
126
+ self.top_point = top_point
127
+ self.n_steps_per_frame = n_steps_per_frame
128
+ ```
129
+
130
+ For Scene subclasses used as "configuration":
131
+
132
+ ```python
133
+ # ManimGL (3b1b)
134
+ class GaltonBoard(InteractiveScene):
135
+ random_seed = 1
136
+ pegs_per_row = 15
137
+ n_rows = 5
138
+ spacing = 1.0
139
+ bucket_style = dict(fill_color=GREY_D, fill_opacity=1.0)
140
+
141
+ # ManimCE -- exactly the same! Class attributes work fine.
142
+ class GaltonBoard(Scene):
143
+ random_seed = 1
144
+ pegs_per_row = 15
145
+ n_rows = 5
146
+ spacing = 1.0
147
+ bucket_style = dict(fill_color=GREY_D, fill_opacity=1.0)
148
+ ```
149
+
150
+ ## Camera and Frame Access
151
+
152
+ ### self.frame to self.camera.frame
153
+
154
+ ```python
155
+ # ManimGL (3b1b)
156
+ frame = self.frame
157
+ frame.set_height(10)
158
+ self.play(frame.animate.move_to(LEFT))
159
+ self.play(frame.animate.scale(0.5))
160
+ frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))
161
+
162
+ # ManimCE (MovingCameraScene)
163
+ class MyScene(MovingCameraScene):
164
+ def construct(self):
165
+ frame = self.camera.frame
166
+ self.play(frame.animate.set(width=10))
167
+ self.play(frame.animate.move_to(LEFT))
168
+ self.play(frame.animate.scale(0.5))
169
+ frame.add_updater(lambda m, dt: m.rotate(-0.1 * dt))
170
+ ```
171
+
172
+ ### frame.reorient() to set_camera_orientation()
173
+
174
+ ```python
175
+ # ManimGL (3b1b) -- 3D camera
176
+ frame.reorient(20, 70)
177
+ self.play(frame.animate.reorient(-30, 60))
178
+
179
+ # ManimCE (ThreeDScene)
180
+ class MyScene(ThreeDScene):
181
+ def construct(self):
182
+ self.set_camera_orientation(phi=70 * DEGREES, theta=20 * DEGREES)
183
+ self.move_camera(phi=60 * DEGREES, theta=-30 * DEGREES, run_time=2)
184
+ # Or for continuous rotation:
185
+ self.begin_ambient_camera_rotation(rate=0.2)
186
+ ```
187
+
188
+ ### fix_in_frame() to add_fixed_in_frame_mobjects()
189
+
190
+ ```python
191
+ # ManimGL (3b1b)
192
+ equation.fix_in_frame()
193
+ # Or:
194
+ mob.always.fix_in_frame()
195
+
196
+ # ManimCE (ThreeDScene)
197
+ class MyScene(ThreeDScene):
198
+ def construct(self):
199
+ equation = MathTex(r"E = mc^2")
200
+ self.add_fixed_in_frame_mobjects(equation)
201
+ # Now equation stays fixed while 3D camera moves
202
+ ```
203
+
204
+ ## LaTeX / Text Classes
205
+
206
+ ### Tex / OldTex / OldTexText to MathTex / Tex
207
+
208
+ ```python
209
+ # ManimGL (3b1b) -- RECENT code
210
+ formula = Tex(R"\frac{d}{dx} e^x = e^x", t2c={R"e^x": YELLOW})
211
+ label = TexText("Hello World")
212
+
213
+ # ManimGL (3b1b) -- OLDER code (pre-2020)
214
+ formula = OldTex(R"\frac{d}{dx} e^x = e^x")
215
+ label = OldTexText("Hello World")
216
+
217
+ # ManimCE
218
+ formula = MathTex(r"\frac{d}{dx} e^x = e^x", tex_to_color_map={r"e^x": YELLOW})
219
+ label = Tex(r"Hello World")
220
+ # Or for plain text:
221
+ label = Text("Hello World")
222
+ ```
223
+
224
+ ### Key LaTeX Differences
225
+
226
+ ```python
227
+ # ManimGL: Uses R"..." raw strings (capital R)
228
+ Tex(R"\pi r^2")
229
+ Tex(R"...", t2c={R"\pi": RED})
230
+
231
+ # ManimCE: Uses r"..." raw strings (lowercase r), different kwarg name
232
+ MathTex(r"\pi r^2")
233
+ MathTex(r"...", tex_to_color_map={r"\pi": RED})
234
+ # Shorthand also works in ManimCE:
235
+ MathTex(r"...", t2c={r"\pi": RED})
236
+ ```
237
+
238
+ ### TexText (styled text in LaTeX) to Tex
239
+
240
+ ```python
241
+ # ManimGL (3b1b)
242
+ title = TexText(R"Moser's Circle Problem", font_size=72)
243
+
244
+ # ManimCE
245
+ title = Tex(r"Moser's Circle Problem", font_size=72)
246
+ # Or often better:
247
+ title = Text("Moser's Circle Problem", font_size=72)
248
+ ```
249
+
250
+ ## Updater Patterns
251
+
252
+ ### f_always to add_updater
253
+
254
+ ```python
255
+ # ManimGL (3b1b)
256
+ dot.f_always.move_to(lambda: axes.i2gp(x_tracker.get_value(), graph))
257
+ f_always(counter.set_value, lambda: len(items))
258
+ frac_label.f_always.move_to(rect.get_center)
259
+
260
+ # ManimCE
261
+ dot.add_updater(lambda m: m.move_to(axes.i2gp(x_tracker.get_value(), graph)))
262
+ counter.add_updater(lambda m: m.set_value(len(items)))
263
+ frac_label.add_updater(lambda m: m.move_to(rect.get_center()))
264
+ ```
265
+
266
+ ### mob.always.method() to add_updater
267
+
268
+ ```python
269
+ # ManimGL (3b1b)
270
+ randy.always.fix_in_frame()
271
+ label.always.next_to(dot, UR, SMALL_BUFF)
272
+
273
+ # ManimCE
274
+ # fix_in_frame doesn't have a direct always equivalent
275
+ # For ThreeDScene: self.add_fixed_in_frame_mobjects(randy)
276
+ label.add_updater(lambda m: m.next_to(dot, UR, SMALL_BUFF))
277
+ ```
278
+
279
+ ### always_redraw (Same in Both!)
280
+
281
+ ```python
282
+ # ManimGL (3b1b)
283
+ h_line = always_redraw(lambda: axes.get_h_line(dot.get_left()))
284
+ brace = always_redraw(Brace, square, UP)
285
+
286
+ # ManimCE -- identical!
287
+ h_line = always_redraw(lambda: axes.get_horizontal_line(dot.get_left()))
288
+ # Note: get_h_line -> get_horizontal_line in ManimCE
289
+ brace = always_redraw(lambda: Brace(square, UP))
290
+ ```
291
+
292
+ ## Coordinate Systems
293
+
294
+ ### Axes Methods
295
+
296
+ ```python
297
+ # ManimGL (3b1b)
298
+ axes.get_h_line(point)
299
+ axes.get_v_line(point)
300
+ axes.get_graph(func)
301
+
302
+ # ManimCE
303
+ axes.get_horizontal_line(point)
304
+ axes.get_vertical_line(point)
305
+ axes.plot(func)
306
+ # Or for compatibility: axes.get_graph(func) also works in ManimCE
307
+ ```
308
+
309
+ ## Specific Mobject Translations
310
+
311
+ ### GlowDot
312
+
313
+ ```python
314
+ # ManimGL (3b1b) -- used in zeta/play.py
315
+ s_dot = Group(TrueDot(), GlowDot())
316
+ s_dot.set_color(YELLOW)
317
+
318
+ # ManimCE -- no GlowDot, approximate with glow effect
319
+ dot = Dot(color=YELLOW, radius=0.08)
320
+ glow = Dot(color=YELLOW, radius=0.3).set_opacity(0.2)
321
+ s_dot = VGroup(glow, dot)
322
+ ```
323
+
324
+ ### set_backstroke()
325
+
326
+ ```python
327
+ # ManimGL (3b1b)
328
+ equations.set_backstroke()
329
+ label.set_backstroke(BLACK, 3)
330
+
331
+ # ManimCE
332
+ equations.set_stroke(BLACK, 5, background=True)
333
+ label.set_stroke(BLACK, 3, background=True)
334
+
335
+ # Or create a helper:
336
+ def set_backstroke(mob, color=BLACK, width=5):
337
+ mob.set_stroke(color, width, background=True)
338
+ return mob
339
+ ```
340
+
341
+ ### make_number_changeable()
342
+
343
+ ```python
344
+ # ManimGL (3b1b) -- from _2025/zeta/play.py
345
+ exp_const_label = Tex(R"c = 0.0000", t2c={"c": RED})
346
+ c_dec = exp_const_label.make_number_changeable("0.0000")
347
+ c_dec.add_updater(lambda m: m.set_value(get_exp_const()))
348
+
349
+ # ManimCE -- use DecimalNumber explicitly
350
+ prefix = MathTex(r"c = ", color=WHITE)
351
+ c_dec = DecimalNumber(0, num_decimal_places=4, color=RED)
352
+ c_dec.add_updater(lambda m: m.set_value(get_exp_const()))
353
+ c_dec.add_updater(lambda m: m.next_to(prefix, RIGHT, buff=0.1))
354
+ label = VGroup(prefix, c_dec)
355
+ ```
356
+
357
+ ### ComplexValueTracker
358
+
359
+ ```python
360
+ # ManimGL (3b1b)
361
+ s_tracker = ComplexValueTracker(1)
362
+ get_s = s_tracker.get_value
363
+
364
+ # ManimCE -- no ComplexValueTracker, use two ValueTrackers
365
+ s_real = ValueTracker(1)
366
+ s_imag = ValueTracker(0)
367
+ get_s = lambda: complex(s_real.get_value(), s_imag.get_value())
368
+ ```
369
+
370
+ ### NumericEmbedding and Custom Mobjects
371
+
372
+ The transformers series uses custom mobjects (`NumericEmbedding`, `WeightMatrix`, `ContextAnimation`, etc.) that don't exist in ManimCE. These need to be reimplemented.
373
+
374
+ ```python
375
+ # ManimGL (3b1b) -- custom helper from transformers/helpers.py
376
+ embedding = NumericEmbedding(length=10).set_width(0.5)
377
+
378
+ # ManimCE -- build from primitives
379
+ def make_embedding(values, width=0.5, font_size=18):
380
+ entries = VGroup()
381
+ for val in values:
382
+ dec = DecimalNumber(val, num_decimal_places=2, font_size=font_size)
383
+ alpha = min(abs(val) / 3, 1)
384
+ color = interpolate_color(BLUE_E, BLUE_B, alpha) if val >= 0 else \
385
+ interpolate_color(RED_E, RED_B, alpha)
386
+ dec.set_color(color)
387
+ entries.add(dec)
388
+ entries.arrange(DOWN, buff=0.1)
389
+ brackets = MathTex(r"\left[ \right]", font_size=36)
390
+ left = brackets[0][:1]
391
+ right = brackets[0][1:]
392
+ left.stretch_to_fit_height(entries.height + 0.3).next_to(entries, LEFT, buff=0.1)
393
+ right.stretch_to_fit_height(entries.height + 0.3).next_to(entries, RIGHT, buff=0.1)
394
+ return VGroup(left, entries, right).set_width(width)
395
+ ```
396
+
397
+ ## 3D-Specific Translations
398
+
399
+ ### Camera Euler Angles
400
+
401
+ ```python
402
+ # ManimGL (3b1b)
403
+ self.camera.frame.set_euler_angles(
404
+ theta=-30 * DEGREES,
405
+ phi=70 * DEGREES,
406
+ )
407
+ self.camera.frame.increment_phi(-10 * DEGREES)
408
+ self.camera.frame.increment_theta(-20 * DEGREES)
409
+
410
+ # ManimCE (ThreeDScene)
411
+ self.set_camera_orientation(phi=70 * DEGREES, theta=-30 * DEGREES)
412
+ self.move_camera(phi=60 * DEGREES, theta=-50 * DEGREES)
413
+ ```
414
+
415
+ ### Surface and TexturedSurface
416
+
417
+ ```python
418
+ # ManimGL (3b1b)
419
+ torus = Torus(r1=1, r2=1)
420
+ sphere = Sphere(radius=3, resolution=torus.resolution)
421
+ earth = TexturedSurface(sphere, "EarthTextureMap", "NightEarthTextureMap")
422
+ mesh = SurfaceMesh(earth)
423
+
424
+ # ManimCE
425
+ torus = Torus(major_radius=1, minor_radius=1)
426
+ sphere = Sphere(radius=3)
427
+ # TexturedSurface not directly available; use Surface with custom func
428
+ # SurfaceMesh: not available, approximate with wireframe
429
+ ```
430
+
431
+ ### Light Source
432
+
433
+ ```python
434
+ # ManimGL (3b1b)
435
+ light = self.camera.light_source
436
+ self.play(light.move_to(3 * IN))
437
+
438
+ # ManimCE -- lighting is handled differently
439
+ # ManimCE uses ThreeDScene lighting config, not a movable light object
440
+ ```
441
+
442
+ ## Syntax Differences
443
+
444
+ ### set_anim_args (ManimGL Only)
445
+
446
+ ```python
447
+ # ManimGL (3b1b)
448
+ rect.animate.next_to(tale, RIGHT, buff=LARGE_BUFF).set_anim_args(rate_func=linear)
449
+
450
+ # ManimCE
451
+ # Pass rate_func to self.play() instead
452
+ self.play(
453
+ rect.animate.next_to(tale, RIGHT, buff=LARGE_BUFF),
454
+ rate_func=linear,
455
+ )
456
+ ```
457
+
458
+ ### VGroup Generator Syntax
459
+
460
+ ```python
461
+ # ManimGL (3b1b) -- generator inside VGroup (recent ManimGL feature)
462
+ embeddings = VGroup(
463
+ NumericEmbedding(length=10).set_width(0.5).next_to(rect, DOWN, buff=1.5)
464
+ for rect in all_rects
465
+ )
466
+
467
+ # ManimCE -- must use * unpacking or explicit list
468
+ embeddings = VGroup(*[
469
+ make_embedding([0]*10).next_to(rect, DOWN, buff=1.5)
470
+ for rect in all_rects
471
+ ])
472
+ ```
473
+
474
+ ### time_span in Animations
475
+
476
+ ```python
477
+ # ManimGL (3b1b)
478
+ self.play(
479
+ FadeIn(elements, time_span=(1, 2)),
480
+ Write(text),
481
+ run_time=3,
482
+ )
483
+
484
+ # ManimCE -- no time_span, use AnimationGroup or separate plays
485
+ self.play(Write(text), run_time=1)
486
+ self.play(FadeIn(elements), run_time=1)
487
+ ```
488
+
489
+ ## Import Translations
490
+
491
+ ```python
492
+ # ManimGL (3b1b)
493
+ from manim_imports_ext import * # Their universal import
494
+ from manimlib import * # Direct manimlib import
495
+ from manimlib.animation.creation import ShowCreation
496
+ from manimlib.scene.interactive_scene import InteractiveScene
497
+
498
+ # ManimCE
499
+ from manim import * # Everything you need
500
+ ```
501
+
502
+ ## Complete Translation Example
503
+
504
+ ### ManimGL Original (from codebase)
505
+
506
+ ```python
507
+ from manim_imports_ext import *
508
+
509
+ class CircumferenceToArea(InteractiveScene):
510
+ def construct(self):
511
+ t2c = {"{r}": BLUE}
512
+ circum_formula = Tex(R"\text{Circumference} = 2 \pi {r}", t2c=t2c)
513
+ radius = 3
514
+ circle = Circle(radius=radius)
515
+ circle.set_stroke(YELLOW, 5)
516
+ r_group = VGroup(
517
+ Line(ORIGIN, radius * RIGHT).set_stroke(WHITE, 3),
518
+ Tex(R"r", font_size=72).set_color(BLUE),
519
+ )
520
+ self.add(circle, r_group)
521
+ self.play(
522
+ ShowCreation(circle),
523
+ Rotate(r_group, TAU, about_point=ORIGIN),
524
+ run_time=3,
525
+ )
526
+ ```
527
+
528
+ ### ManimCE Translation
529
+
530
+ ```python
531
+ from manim import *
532
+
533
+ class CircumferenceToArea(Scene):
534
+ def construct(self):
535
+ t2c = {"{r}": BLUE}
536
+ circum_formula = MathTex(
537
+ r"\text{Circumference} = 2 \pi {r}",
538
+ tex_to_color_map=t2c,
539
+ )
540
+ radius = 3
541
+ circle = Circle(radius=radius)
542
+ circle.set_stroke(YELLOW, 5)
543
+ r_group = VGroup(
544
+ Line(ORIGIN, radius * RIGHT).set_stroke(WHITE, 3),
545
+ MathTex(r"r", font_size=72).set_color(BLUE),
546
+ )
547
+ self.add(circle, r_group)
548
+ self.play(
549
+ Create(circle),
550
+ Rotate(r_group, TAU, about_point=ORIGIN),
551
+ run_time=3,
552
+ )
553
+ ```
554
+
555
+ ## Quick Reference Table
556
+
557
+ | ManimGL (3b1b) | ManimCE | Frequency |
558
+ |-----------------|---------|-----------|
559
+ | `ShowCreation(mob)` | `Create(mob)` | Very high |
560
+ | `InteractiveScene` | `Scene` | Very high |
561
+ | `Tex(R"...", t2c={})` | `MathTex(r"...", tex_to_color_map={})` | Very high |
562
+ | `OldTex(R"...")` | `MathTex(r"...")` | High (older files) |
563
+ | `OldTexText("...")` | `Tex("...")` or `Text("...")` | High (older files) |
564
+ | `TexText("...")` | `Tex("...")` or `Text("...")` | High |
565
+ | `CONFIG = {...}` | `__init__` parameters | Very high |
566
+ | `self.frame` | `self.camera.frame` (MovingCameraScene) | High |
567
+ | `frame.reorient(th, ph)` | `self.set_camera_orientation(phi, theta)` | Medium |
568
+ | `mob.fix_in_frame()` | `self.add_fixed_in_frame_mobjects(mob)` | Medium |
569
+ | `mob.f_always.method(func)` | `mob.add_updater(lambda m: m.method(func()))` | Medium |
570
+ | `f_always(mob.set_value, func)` | `mob.add_updater(lambda m: m.set_value(func()))` | Medium |
571
+ | `mob.always.fix_in_frame()` | `self.add_fixed_in_frame_mobjects(mob)` | Low |
572
+ | `set_backstroke(color, w)` | `set_stroke(color, w, background=True)` | Medium |
573
+ | `make_number_changeable()` | Use `DecimalNumber` with updater | Low |
574
+ | `GlowDot` | `Dot` with transparent larger `Dot` behind | Low |
575
+ | `ComplexValueTracker` | Two `ValueTracker`s (real, imag) | Low |
576
+ | `axes.get_h_line()` | `axes.get_horizontal_line()` | Medium |
577
+ | `axes.get_v_line()` | `axes.get_vertical_line()` | Medium |
578
+ | `axes.get_graph()` | `axes.plot()` | Medium |
579
+ | `.set_anim_args(rate_func=...)` | Pass `rate_func` to `self.play()` | Low |
580
+ | `VGroup(x for x in items)` | `VGroup(*[x for x in items])` | Medium |
581
+ | `time_span=(0, 1)` in anim | Not available; restructure animations | Low |
582
+
583
+ ## Best Practices for Translation
584
+
585
+ 1. **Start with imports**: Replace `from manim_imports_ext import *` with `from manim import *`
586
+ 2. **Find-replace animations**: `ShowCreation` to `Create` globally
587
+ 3. **Find-replace scene classes**: `InteractiveScene` to `Scene`
588
+ 4. **Convert CONFIG dicts**: Move to `__init__` parameters
589
+ 5. **Fix LaTeX classes**: `Tex(R"...")` to `MathTex(r"...")`, `OldTex` to `MathTex`
590
+ 6. **Fix camera access**: `self.frame` to `self.camera.frame` and use proper scene type
591
+ 7. **Fix updater patterns**: `f_always` to `add_updater`
592
+ 8. **Test incrementally**: Translate one scene at a time, render to verify
593
+ 9. **Skip custom mobjects**: Reimplement 3b1b-specific helpers from scratch
594
+ 10. **Check coordinate system methods**: Many method names differ slightly