aboutsummaryrefslogtreecommitdiffstats
path: root/scenes
diff options
context:
space:
mode:
Diffstat (limited to 'scenes')
-rw-r--r--scenes/overlay.py20
-rw-r--r--scenes/tiktok.py36
-rw-r--r--scenes/v10_buffon.py92
-rw-r--r--scenes/v11_collatz.py98
-rw-r--r--scenes/v12_simpson.py144
-rw-r--r--scenes/v13_cuerda.py118
-rw-r--r--scenes/v14_gabriel.py82
-rw-r--r--scenes/v15_mobius.py138
-rw-r--r--scenes/v16_bayes.py154
-rw-r--r--scenes/v17_cicloide.py188
-rw-r--r--scenes/v18_dados.py174
-rw-r--r--scenes/v1_montyhall.py44
-rw-r--r--scenes/v2_nueves.py74
-rw-r--r--scenes/v3_cumple.py52
-rw-r--r--scenes/v4_luna.py64
-rw-r--r--scenes/v5_japones.py62
-rw-r--r--scenes/v6_benford.py66
-rw-r--r--scenes/v7_hilbert.py56
-rw-r--r--scenes/v8_reuleaux.py108
-rw-r--r--scenes/v9_regla72.py68
20 files changed, 919 insertions, 919 deletions
diff --git a/scenes/overlay.py b/scenes/overlay.py
index 0a3eb71..d8d735b 100644
--- a/scenes/overlay.py
+++ b/scenes/overlay.py
@@ -1,31 +1,31 @@
# -*- coding: utf-8 -*-
-"""Capa de interfaz del canal (chip, barra de progreso y subtitulos) para los
-videos renderizados en Blender. Se renderiza con --transparent y se compone
-encima del 3D, asi el estilo sale del mismo codigo que los videos de Manim.
+"""Channel UI layer (chip, progress bar and subtitles) for the videos rendered
+in Blender. It is rendered with --transparent and composited over the 3D, so
+the style comes from the same code as the Manim videos.
NAME=bolapeluda CHIP=Topología CHIPCOL=celeste manim --transparent ...
-Tambien escribe out/<name>_timeline.json, que es lo que despues leen el script
-de Blender (para animar) y build_video.py (para colocar el audio).
+It also writes out/<name>_timeline.json, which the Blender script (to animate)
+and build_video.py (to place the audio) read afterwards.
"""
import os, sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from manim import *
from tiktok import *
-COLORES = {"ambar": AMBAR, "verde": VERDE, "rosa": ROSA, "celeste": CELESTE}
+PALETTE = {"ambar": AMBER, "verde": C_GREEN, "rosa": C_PINK, "celeste": C_SKY}
class Overlay(TikTok):
NAME = os.environ.get("NAME", "")
def backdrop(self):
- return VGroup() # el fondo punteado va aparte, debajo del 3D
+ return VGroup() # the dotted background goes separately, under the 3D
def construct(self):
self.prepare()
chip = self.chip(os.environ.get("CHIP", ""),
- COLORES[os.environ.get("CHIPCOL", "ambar")])
+ PALETTE[os.environ.get("CHIPCOL", "ambar")])
self.add(chip)
for i in range(len(self.segs)):
with self.beat(i) as b:
@@ -33,8 +33,8 @@ class Overlay(TikTok):
self.finish()
-class Fondo(TikTok):
- """Un solo frame con la trama de puntos, para usar de fondo."""
+class Backdrop(TikTok):
+ """A single frame with the dot pattern, to use as background."""
NAME = "fondo"
def construct(self):
diff --git a/scenes/tiktok.py b/scenes/tiktok.py
index 7e2ad2d..584210e 100644
--- a/scenes/tiktok.py
+++ b/scenes/tiktok.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
-"""Base comun para los videos verticales: formato 9:16, subtitulos,
-barra de progreso y un sistema de 'beats' sincronizados con el audio."""
+"""Common base for the vertical videos: 9:16 format, subtitles,
+progress bar and a system of 'beats' synced with the audio."""
import json, os
from contextlib import contextmanager
from manim import *
-# --- formato TikTok 1080x1920 -------------------------------------------------
+# --- TikTok format 1080x1920 --------------------------------------------------
if os.environ.get("DRAFT"):
config.pixel_width, config.pixel_height = 540, 960
else:
@@ -18,19 +18,19 @@ config.background_color = "#0B0F1A"
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
FONT = "Roboto"
-AMBAR = "#FFD166"
-VERDE = "#06D6A0"
-ROSA = "#EF476F"
-CELESTE = "#4CC9F0"
-GRIS = "#8D99AE"
-
-GAP = 0.30 # silencio entre segmentos
-SUB_Y = -4.25 # los subtitulos van arriba de la UI de TikTok
+AMBER = "#FFD166"
+C_GREEN = "#06D6A0"
+C_PINK = "#EF476F"
+C_SKY = "#4CC9F0"
+C_GRAY = "#8D99AE"
+
+GAP = 0.30 # silence between segments
+SUB_Y = -4.25 # subtitles sit above the TikTok UI
TOP_Y = 6.45
class _Beat:
- """Acumula el tiempo usado dentro de un segmento para poder rellenar el resto."""
+ """Accumulates the time used inside a segment so the rest can be filled."""
def __init__(self, scene, floor):
self.s, self.floor, self.used = scene, floor, 0.0
@@ -63,7 +63,7 @@ class _Beat:
class TikTok(Scene):
NAME = ""
- # -- infraestructura ------------------------------------------------------
+ # -- infrastructure -------------------------------------------------------
def prepare(self):
with open(os.path.join(ROOT, "audio", self.NAME, "segments.json"), encoding="utf-8") as f:
self.data = json.load(f)
@@ -88,7 +88,7 @@ class TikTok(Scene):
track = Rectangle(width=w, height=0.075, stroke_width=0,
fill_color="#1B2233", fill_opacity=1).move_to(UP * (TOP_Y + 1.15))
bar = Rectangle(width=0.002, height=0.075, stroke_width=0,
- fill_color=AMBAR, fill_opacity=1).move_to(track.get_left(), LEFT)
+ fill_color=AMBER, fill_opacity=1).move_to(track.get_left(), LEFT)
self.elapsed = 0.0
total, left, y = self._expected, -w / 2, track.get_y()
@@ -103,7 +103,7 @@ class TikTok(Scene):
self.add(track, bar)
def subtitle(self, text):
- """Cambia el subtitulo sin consumir tiempo de animacion."""
+ """Changes the subtitle without spending animation time."""
if self._sub:
self.remove(self._sub)
t = Text(text, font=FONT, font_size=44, weight=BOLD, color=WHITE,
@@ -118,7 +118,7 @@ class TikTok(Scene):
@contextmanager
def beat(self, i, sub=True):
- """Bloque sincronizado con el segmento i de audio."""
+ """Block synced with audio segment i."""
if sub:
self.subtitle(self.segs[i]["sub"])
b = _Beat(self, self.segs[i]["dur"])
@@ -139,8 +139,8 @@ class TikTok(Scene):
json.dump({"name": self.NAME, "gap": GAP, "total": round(self.clock, 3),
"beats": self.timeline}, f, indent=2)
- # -- helpers visuales -----------------------------------------------------
- def chip(self, text, color=AMBAR):
+ # -- visual helpers -------------------------------------------------------
+ def chip(self, text, color=AMBER):
t = Text(text, font=FONT, font_size=34, weight=BOLD, color="#0B0F1A")
box = RoundedRectangle(corner_radius=0.3, stroke_width=0, fill_color=color,
fill_opacity=1, width=t.width + 0.7, height=t.height + 0.45)
diff --git a/scenes/v10_buffon.py b/scenes/v10_buffon.py
index 35ee4e0..557d927 100644
--- a/scenes/v10_buffon.py
+++ b/scenes/v10_buffon.py
@@ -4,13 +4,13 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from manim import *
from tiktok import *
-D = 1.1 # separacion entre rayas = largo de la aguja
-Y0 = 0.35 # raya mas baja
+D = 1.1 # line spacing = needle length
+Y0 = 0.35 # lowest line
NLIN = 5
SEED, N1, N2 = 36, 60, 200
-def tirar(n):
+def throw(n):
rng = np.random.default_rng(SEED)
x = rng.uniform(-3.9, 3.9, n)
y = rng.uniform(Y0 + 0.1, Y0 + (NLIN - 1) * D - 0.1, n)
@@ -18,8 +18,8 @@ def tirar(n):
dx, dy = D / 2 * np.cos(th), D / 2 * np.sin(th)
p1 = np.stack([x - dx, y - dy, np.zeros(n)], axis=1)
p2 = np.stack([x + dx, y + dy, np.zeros(n)], axis=1)
- cruza = np.floor((p1[:, 1] - Y0) / D) != np.floor((p2[:, 1] - Y0) / D)
- return p1, p2, cruza
+ crosses = np.floor((p1[:, 1] - Y0) / D) != np.floor((p2[:, 1] - Y0) / D)
+ return p1, p2, crosses
class Buffon(TikTok):
@@ -27,10 +27,10 @@ class Buffon(TikTok):
def construct(self):
self.prepare()
- chip = self.chip("π sin círculos", ROSA)
- p1, p2, cruza = tirar(N2)
+ chip = self.chip("π sin círculos", C_PINK)
+ p1, p2, crosses = throw(N2)
- rayas = VGroup(*[Line([-4.2, Y0 + k * D, 0], [4.2, Y0 + k * D, 0],
+ stripes = VGroup(*[Line([-4.2, Y0 + k * D, 0], [4.2, Y0 + k * D, 0],
stroke_width=4, color="#33405C") for k in range(NLIN)])
with self.beat(0) as b:
@@ -38,7 +38,7 @@ class Buffon(TikTok):
self.fit(Text("tiro agujas al piso", font=FONT, font_size=52,
weight=BOLD, color=WHITE), 8.2),
self.fit(Text("y sale π", font=FONT, font_size=64,
- weight=BOLD, color=AMBAR), 8.2),
+ weight=BOLD, color=AMBER), 8.2),
).arrange(DOWN, buff=0.32).move_to(UP * 2.4)
b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.45)
b.play(FadeIn(hook[0], shift=UP * 0.15), run_time=0.6)
@@ -46,105 +46,105 @@ class Buffon(TikTok):
with self.beat(1) as b:
b.play(FadeOut(hook), run_time=0.35)
- b.play(LaggedStart(*[Create(r) for r in rayas], lag_ratio=0.12), run_time=0.9)
+ b.play(LaggedStart(*[Create(r) for r in stripes], lag_ratio=0.12), run_time=0.9)
demo = Line([-1.0, Y0 + D, 0], [-1.0, Y0 + 2 * D, 0],
- stroke_width=9, color=AMBAR)
+ stroke_width=9, color=AMBER)
med = DoubleArrow([0.2, Y0 + D, 0], [0.2, Y0 + 2 * D, 0], buff=0,
- color=VERDE, stroke_width=6, tip_length=0.2)
- lab = Text("mismo largo", font=FONT, font_size=32, weight=BOLD, color=VERDE)
+ color=C_GREEN, stroke_width=6, tip_length=0.2)
+ lab = Text("mismo largo", font=FONT, font_size=32, weight=BOLD, color=C_GREEN)
lab.next_to(med, RIGHT, buff=0.25)
b.play(Create(demo), run_time=0.5)
b.play(GrowArrow(med), FadeIn(lab), run_time=0.6)
- agujas = VGroup(*[Line(p1[i], p2[i], stroke_width=4.5, color="#7C8AA8")
+ needles = VGroup(*[Line(p1[i], p2[i], stroke_width=4.5, color="#7C8AA8")
for i in range(N2)])
with self.beat(2) as b:
b.play(FadeOut(VGroup(demo, med, lab)), run_time=0.3)
- b.play(LaggedStart(*[FadeIn(agujas[i]) for i in range(N1)],
+ b.play(LaggedStart(*[FadeIn(needles[i]) for i in range(N1)],
lag_ratio=0.012), run_time=max(1.1, b.floor - 0.5))
with self.beat(3) as b:
- hit = [agujas[i] for i in range(N1) if cruza[i]]
- miss = [agujas[i] for i in range(N1) if not cruza[i]]
- b.play(*[a.animate.set_stroke(AMBAR, 6) for a in hit],
+ hit = [needles[i] for i in range(N1) if crosses[i]]
+ miss = [needles[i] for i in range(N1) if not crosses[i]]
+ b.play(*[a.animate.set_stroke(AMBER, 6) for a in hit],
*[a.animate.set_stroke("#46526E", 3.5) for a in miss], run_time=1.0)
- c1 = int(cruza[:N1].sum())
+ c1 = int(crosses[:N1].sum())
- def marcador(n, c, y=-0.75):
+ def marker(n, c, y=-0.75):
g = VGroup(
- VGroup(Text("tiradas", font=FONT, font_size=30, color=GRIS),
+ VGroup(Text("tiradas", font=FONT, font_size=30, color=C_GRAY),
Text(str(n), font=FONT, font_size=62, weight=BOLD, color=WHITE)
).arrange(DOWN, buff=0.1),
- VGroup(Text("cruzan", font=FONT, font_size=30, color=GRIS),
- Text(str(c), font=FONT, font_size=62, weight=BOLD, color=AMBAR)
+ VGroup(Text("cruzan", font=FONT, font_size=30, color=C_GRAY),
+ Text(str(c), font=FONT, font_size=62, weight=BOLD, color=AMBER)
).arrange(DOWN, buff=0.1),
).arrange(RIGHT, buff=1.5).move_to([0, y, 0])
return g
- marc = marcador(N1, c1)
+ marker_m = marker(N1, c1)
with self.beat(4) as b:
- b.play(FadeIn(marc, shift=UP * 0.15), run_time=0.8)
+ b.play(FadeIn(marker_m, shift=UP * 0.15), run_time=0.8)
with self.beat(5) as b:
f = MathTex(r"\frac{2 \times \text{tiradas}}{\text{cruces}}",
- color=CELESTE).scale(1.25).move_to(DOWN * 2.45)
+ color=C_SKY).scale(1.25).move_to(DOWN * 2.45)
b.play(Write(f), run_time=1.1)
with self.beat(6) as b:
- est = 2 * N1 / c1
- res = MathTex(r"= %s" % f"{est:.4f}".replace(".", "{,}"),
- color=VERDE).scale(1.45)
+ estimate = 2 * N1 / c1
+ res = MathTex(r"= %s" % f"{estimate:.4f}".replace(".", "{,}"),
+ color=C_GREEN).scale(1.45)
res.next_to(f, RIGHT, buff=0.4)
grp = VGroup(f, res)
b.play(Write(res), run_time=0.8)
b.play(grp.animate.move_to(DOWN * 2.45), run_time=0.4)
- b.play(Flash(res, color=VERDE, line_length=0.5, num_lines=16,
+ b.play(Flash(res, color=C_GREEN, line_length=0.5, num_lines=16,
flash_radius=1.4), run_time=0.6)
- c2 = int(cruza.sum())
+ c2 = int(crosses.sum())
with self.beat(7) as b:
- hit = [agujas[i] for i in range(N1, N2) if cruza[i]]
- miss = [agujas[i] for i in range(N1, N2) if not cruza[i]]
+ hit = [needles[i] for i in range(N1, N2) if crosses[i]]
+ miss = [needles[i] for i in range(N1, N2) if not crosses[i]]
for a in hit:
- a.set_stroke(AMBAR, 6)
+ a.set_stroke(AMBER, 6)
for a in miss:
a.set_stroke("#46526E", 3.5)
- b.play(LaggedStart(*[FadeIn(agujas[i]) for i in range(N1, N2)],
+ b.play(LaggedStart(*[FadeIn(needles[i]) for i in range(N1, N2)],
lag_ratio=0.004), run_time=max(1.0, b.floor - 1.3))
est2 = 2 * N2 / c2
- nm = marcador(N2, c2)
+ nm = marker(N2, c2)
nres = MathTex(r"= %s" % f"{est2:.4f}".replace(".", "{,}"),
- color=VERDE).scale(1.45).next_to(f, RIGHT, buff=0.4)
- b.play(Transform(marc, nm), Transform(res, nres), run_time=0.9)
+ color=C_GREEN).scale(1.45).next_to(f, RIGHT, buff=0.4)
+ b.play(Transform(marker_m, nm), Transform(res, nres), run_time=0.9)
with self.beat(8) as b:
- pi = MathTex(r"\pi = 3{,}14159\ldots", color=AMBAR).scale(1.5)
+ pi = MathTex(r"\pi = 3{,}14159\ldots", color=AMBER).scale(1.5)
pi.move_to(UP * 5.5)
b.play(Write(pi), run_time=1.0)
- b.play(Circumscribe(pi, color=AMBAR, buff=0.25, stroke_width=6), run_time=0.8)
+ b.play(Circumscribe(pi, color=AMBER, buff=0.25, stroke_width=6), run_time=0.8)
with self.beat(9) as b:
- b.play(FadeOut(VGroup(marc, pi, f, res)), run_time=0.45)
+ b.play(FadeOut(VGroup(marker_m, pi, f, res)), run_time=0.45)
t = VGroup(
self.fit(Text("no hay ningún círculo", font=FONT, font_size=48,
weight=BOLD, color=WHITE), 8.2),
self.fit(Text("y π aparece igual", font=FONT, font_size=48,
- weight=BOLD, color=AMBAR), 8.2),
+ weight=BOLD, color=AMBER), 8.2),
).arrange(DOWN, buff=0.35).move_to(DOWN * 1.5)
b.play(FadeIn(t[0], shift=UP * 0.15), run_time=0.6)
b.play(FadeIn(t[1], shift=UP * 0.15), run_time=0.7)
with self.beat(10) as b:
b.play(FadeOut(t), run_time=0.35)
- cta = VGroup(
+ count_txt = VGroup(
self.fit(Text("aguja de Buffon", font=FONT, font_size=58,
- weight=BOLD, color=AMBAR), 8.0),
+ weight=BOLD, color=AMBER), 8.0),
self.fit(Text("hacelo con fósforos", font=FONT, font_size=44,
weight=BOLD, color=WHITE), 8.0),
).arrange(DOWN, buff=0.35).move_to(DOWN * 1.5)
- b.play(Write(cta[0]), run_time=0.8)
- b.play(FadeIn(cta[1], shift=UP * 0.15), run_time=0.6)
+ b.play(Write(count_txt[0]), run_time=0.8)
+ b.play(FadeIn(count_txt[1], shift=UP * 0.15), run_time=0.6)
self.finish()
diff --git a/scenes/v11_collatz.py b/scenes/v11_collatz.py
index 49436b8..20c7ccd 100644
--- a/scenes/v11_collatz.py
+++ b/scenes/v11_collatz.py
@@ -16,8 +16,8 @@ def seq(n):
return s
-def curva(sq, color=AMBAR, sw=5, mx=None, nx=None, log=False):
- """Trayectoria como poligonal. mx/nx permiten compartir escala entre curvas."""
+def curve_obj(sq, color=AMBER, sw=5, mx=None, nx=None, log=False):
+ """Trajectory as a polyline. mx/nx allow sharing the scale between curves."""
mx = mx or max(sq)
nx = nx or len(sq)
if log:
@@ -43,29 +43,29 @@ class Collatz(TikTok):
def construct(self):
self.prepare()
- chip = self.chip("Abierto desde 1937", ROSA)
+ chip = self.chip("Abierto desde 1937", C_PINK)
with self.beat(0) as b:
- n = self.big("27", 150, AMBAR).move_to(UP * 1.9)
+ n = self.big("27", 150, AMBER).move_to(UP * 1.9)
cap = self.fit(Text("agarrá cualquier número", font=FONT, font_size=50,
weight=BOLD, color=WHITE), 8.2).move_to(DOWN * 0.3)
b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.45)
b.play(FadeIn(n, scale=0.6), run_time=0.45)
for v in ("6", "19", "41"):
- b.play(Transform(n, self.big(v, 150, AMBAR).move_to(UP * 1.9)), run_time=0.26)
+ b.play(Transform(n, self.big(v, 150, AMBER).move_to(UP * 1.9)), run_time=0.26)
b.play(FadeIn(cap, shift=UP * 0.15), run_time=0.5)
- def regla(txt, op, col):
+ def ruler(txt, op, col):
a = Text(txt, font=FONT, font_size=46, weight=BOLD, color=col)
- fl = Arrow(ORIGIN, RIGHT * 0.85, buff=0, color=GRIS, stroke_width=6,
+ fl = Arrow(ORIGIN, RIGHT * 0.85, buff=0, color=C_GRAY, stroke_width=6,
max_tip_length_to_length_ratio=0.35)
c = Text(op, font=FONT, font_size=52, weight=BOLD, color=WHITE)
return VGroup(a, fl, c).arrange(RIGHT, buff=0.35)
with self.beat(1) as b:
b.play(FadeOut(VGroup(n, cap)), run_time=0.3)
- r1 = regla("es PAR", "÷ 2", CELESTE)
- r2 = regla("es IMPAR", "× 3 + 1", AMBAR)
+ r1 = ruler("es PAR", "÷ 2", C_SKY)
+ r2 = ruler("es IMPAR", "× 3 + 1", AMBER)
rr = VGroup(r1, r2).arrange(DOWN, buff=0.7).move_to(UP * 1.6)
self.fit(rr, 8.2)
b.play(FadeIn(r1, shift=UP * 0.2), run_time=0.7)
@@ -74,12 +74,12 @@ class Collatz(TikTok):
s6 = seq(6)
with self.beat(2) as b:
b.play(rr.animate.scale(0.72).move_to(UP * 5.2), run_time=0.5)
- seis = self.big("6", 140, VERDE).move_to(UP * 1.0)
- b.play(FadeIn(seis, scale=0.6), run_time=0.6)
+ six = self.big("6", 140, C_GREEN).move_to(UP * 1.0)
+ b.play(FadeIn(six, scale=0.6), run_time=0.6)
with self.beat(3) as b:
- b.play(FadeOut(seis), run_time=0.25)
- tiles = VGroup(*[tile(v, VERDE if v == 1 else (CELESTE if v % 2 == 0 else AMBAR))
+ b.play(FadeOut(six), run_time=0.25)
+ tiles = VGroup(*[tile(v, C_GREEN if v == 1 else (C_SKY if v % 2 == 0 else AMBER))
for v in s6])
fila1 = VGroup(*tiles[:5]).arrange(RIGHT, buff=0.28)
fila2 = VGroup(*tiles[5:]).arrange(RIGHT, buff=0.28)
@@ -89,83 +89,83 @@ class Collatz(TikTok):
lag_ratio=0.5), run_time=max(1.4, b.floor - 0.4))
with self.beat(4) as b:
- b.play(Circumscribe(tiles[-1], color=VERDE, buff=0.12, stroke_width=6),
+ b.play(Circumscribe(tiles[-1], color=C_GREEN, buff=0.12, stroke_width=6),
run_time=0.7)
b.play(FadeOut(grid), run_time=0.35)
- siete = self.big("7", 140, AMBAR).move_to(UP * 1.0)
- b.play(FadeIn(siete, scale=0.6), run_time=0.5)
+ seven = self.big("7", 140, AMBER).move_to(UP * 1.0)
+ b.play(FadeIn(seven, scale=0.6), run_time=0.5)
base = Line([X0 - 0.25, Y0, 0], [X1 + 0.25, Y0, 0], stroke_width=4, color="#33405C")
- uno = Text("1", font=FONT, font_size=32, weight=BOLD, color=VERDE)
- uno.next_to(base.get_start(), LEFT, buff=0.12)
+ one_val = Text("1", font=FONT, font_size=32, weight=BOLD, color=C_GREEN)
+ one_val.next_to(base.get_start(), LEFT, buff=0.12)
s7 = seq(7)
with self.beat(5) as b:
- b.play(FadeOut(siete), run_time=0.25)
- c7, p7 = curva(s7, AMBAR, 6)
- pico = Text("52", font=FONT, font_size=34, weight=BOLD, color=AMBAR)
- pico.next_to([p7[s7.index(max(s7))][0], Y1, 0], UP, buff=0.12)
- b.play(FadeIn(base), FadeIn(uno), run_time=0.35)
+ b.play(FadeOut(seven), run_time=0.25)
+ c7, p7 = curve_obj(s7, AMBER, 6)
+ peak_y = Text("52", font=FONT, font_size=34, weight=BOLD, color=AMBER)
+ peak_y.next_to([p7[s7.index(max(s7))][0], Y1, 0], UP, buff=0.12)
+ b.play(FadeIn(base), FadeIn(one_val), run_time=0.35)
b.play(Create(c7), run_time=max(1.2, b.floor - 1.1))
- b.play(FadeIn(pico), run_time=0.4)
+ b.play(FadeIn(peak_y), run_time=0.4)
s27 = seq(27)
with self.beat(6) as b:
- b.play(FadeOut(VGroup(c7, pico)), run_time=0.3)
- c27, p27 = curva(s27, ROSA, 5)
+ b.play(FadeOut(VGroup(c7, peak_y)), run_time=0.3)
+ c27, p27 = curve_obj(s27, C_PINK, 5)
k = s27.index(max(s27))
- top = Text("9.232", font=FONT, font_size=40, weight=BOLD, color=ROSA)
+ top = Text("9.232", font=FONT, font_size=40, weight=BOLD, color=C_PINK)
top.next_to([p27[k][0], Y1, 0], UP, buff=0.12)
- lab = Text("27", font=FONT, font_size=40, weight=BOLD, color=ROSA)
+ lab = Text("27", font=FONT, font_size=40, weight=BOLD, color=C_PINK)
lab.move_to([X0 - 0.05, Y1 + 0.45, 0])
b.play(FadeIn(lab), run_time=0.3)
b.play(Create(c27), run_time=max(1.3, b.floor - 1.0))
b.play(FadeIn(top), run_time=0.4)
with self.beat(7) as b:
- fin = Dot([p27[-1][0], Y0, 0], radius=0.14, color=VERDE)
- pasos = self.fit(Text("111 pasos y cae al 1", font=FONT, font_size=48,
- weight=BOLD, color=VERDE), 8.0).move_to(DOWN * 2.6)
+ fin = Dot([p27[-1][0], Y0, 0], radius=0.14, color=C_GREEN)
+ steps = self.fit(Text("111 pasos y cae al 1", font=FONT, font_size=48,
+ weight=BOLD, color=C_GREEN), 8.0).move_to(DOWN * 2.6)
b.play(FadeIn(fin, scale=0.4), run_time=0.4)
- b.play(Flash(fin, color=VERDE, line_length=0.35, num_lines=14,
+ b.play(Flash(fin, color=C_GREEN, line_length=0.35, num_lines=14,
flash_radius=0.8), run_time=0.6)
- b.play(FadeIn(pasos, shift=UP * 0.15), run_time=0.6)
+ b.play(FadeIn(steps, shift=UP * 0.15), run_time=0.6)
with self.beat(8) as b:
- b.play(FadeOut(VGroup(c27, top, lab, fin, pasos)), run_time=0.4)
- todos = [seq(k) for k in range(2, 80)]
- MX = max(max(s) for s in todos)
- NX = max(len(s) for s in todos)
- cols = [AMBAR, CELESTE, ROSA, VERDE]
- gr = VGroup(*[curva(s, cols[i % 4], 2.4, mx=MX, nx=NX, log=True)[0]
- for i, s in enumerate(todos)])
+ b.play(FadeOut(VGroup(c27, top, lab, fin, steps)), run_time=0.4)
+ everyone = [seq(k) for k in range(2, 80)]
+ MX = max(max(s) for s in everyone)
+ NX = max(len(s) for s in everyone)
+ cols = [AMBER, C_SKY, C_PINK, C_GREEN]
+ gr = VGroup(*[curve_obj(s, cols[i % 4], 2.4, mx=MX, nx=NX, log=True)[0]
+ for i, s in enumerate(everyone)])
gr.set_stroke(opacity=0.65)
b.play(LaggedStart(*[Create(c) for c in gr], lag_ratio=0.02),
run_time=max(1.6, b.floor - 0.9))
- marca = self.fit(Text("todos terminan en 1", font=FONT, font_size=46,
- weight=BOLD, color=VERDE), 8.0).move_to(DOWN * 2.6)
- b.play(FadeIn(marca, shift=UP * 0.15), run_time=0.6)
+ tick_m = self.fit(Text("todos terminan en 1", font=FONT, font_size=46,
+ weight=BOLD, color=C_GREEN), 8.0).move_to(DOWN * 2.6)
+ b.play(FadeIn(tick_m, shift=UP * 0.15), run_time=0.6)
with self.beat(9) as b:
- b.play(FadeOut(VGroup(gr, marca, base, uno, rr)), run_time=0.45)
+ b.play(FadeOut(VGroup(gr, tick_m, base, one_val, rr)), run_time=0.45)
t = VGroup(
self.fit(Text("nadie pudo demostrar", font=FONT, font_size=50,
weight=BOLD, color=WHITE), 8.2),
self.fit(Text("que pasa SIEMPRE", font=FONT, font_size=54,
- weight=BOLD, color=ROSA), 8.2),
+ weight=BOLD, color=C_PINK), 8.2),
).arrange(DOWN, buff=0.35).move_to(UP * 1.2)
b.play(FadeIn(t[0], shift=UP * 0.15), run_time=0.6)
b.play(FadeIn(t[1], scale=0.8), run_time=0.7)
with self.beat(10) as b:
b.play(FadeOut(t), run_time=0.35)
- cta = VGroup(
+ count_txt = VGroup(
self.fit(Text("conjetura de Collatz", font=FONT, font_size=56,
- weight=BOLD, color=AMBAR), 8.0),
+ weight=BOLD, color=AMBER), 8.0),
self.fit(Text("dejá tu número abajo", font=FONT, font_size=46,
weight=BOLD, color=WHITE), 8.0),
).arrange(DOWN, buff=0.38).move_to(UP * 0.8)
- b.play(Write(cta[0]), run_time=0.9)
- b.play(FadeIn(cta[1], shift=UP * 0.15), run_time=0.6)
+ b.play(Write(count_txt[0]), run_time=0.9)
+ b.play(FadeIn(count_txt[1], shift=UP * 0.15), run_time=0.6)
self.finish()
diff --git a/scenes/v12_simpson.py b/scenes/v12_simpson.py
index 6092924..885d9e7 100644
--- a/scenes/v12_simpson.py
+++ b/scenes/v12_simpson.py
@@ -4,23 +4,23 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from manim import *
from tiktok import *
-# datos reales (Charig et al., 1986): tratamiento A vs B para calculos renales
-LEV = (("A", 81, 87), ("B", 234, 270))
-GRA = (("A", 192, 263), ("B", 55, 80))
+# real data (Charig et al., 1986): treatment A vs B for kidney stones
+LEVER = (("A", 81, 87), ("B", 234, 270))
+GRAV_FIELD = (("A", 192, 263), ("B", 55, 80))
TOT = (("A", 81 + 192, 87 + 263), ("B", 234 + 55, 270 + 80))
-BARW = 4.05 # ancho de barra al 100%
-XL = -1.55 # borde izquierdo de las barras
+BARW = 4.05 # bar width at 100%
+XL = -1.55 # left edge of the bars
class Simpson(TikTok):
NAME = "simpson"
- def barra(self, letra, num, den, y, gana):
+ def bar_m(self, letter, num, den, y, wins):
pct = 100.0 * num / den
- col = VERDE if gana else GRIS
- lab = Text(letra, font=FONT, font_size=50, weight=BOLD,
- color=CELESTE if letra == "A" else ROSA)
+ col = C_GREEN if wins else C_GRAY
+ lab = Text(letter, font=FONT, font_size=50, weight=BOLD,
+ color=C_SKY if letter == "A" else C_PINK)
lab.move_to([-3.65, y, 0])
track = RoundedRectangle(corner_radius=0.12, width=BARW, height=0.62,
stroke_width=0, fill_color="#1B2233", fill_opacity=1)
@@ -32,139 +32,139 @@ class Simpson(TikTok):
val.next_to(track, RIGHT, buff=0.22)
return VGroup(lab, track, fill, val)
- def bloque(self, titulo, datos, ytop, ganador):
- t = Text(titulo, font=FONT, font_size=40, weight=BOLD, color=WHITE)
+ def block_obj(self, title, dataset, ytop, winner):
+ t = Text(title, font=FONT, font_size=40, weight=BOLD, color=WHITE)
t.move_to([-3.85, ytop, 0], LEFT)
- b1 = self.barra(datos[0][0], datos[0][1], datos[0][2], ytop - 0.85,
- datos[0][0] == ganador)
- b2 = self.barra(datos[1][0], datos[1][1], datos[1][2], ytop - 1.70,
- datos[1][0] == ganador)
+ b1 = self.bar_m(dataset[0][0], dataset[0][1], dataset[0][2], ytop - 0.85,
+ dataset[0][0] == winner)
+ b2 = self.bar_m(dataset[1][0], dataset[1][1], dataset[1][2], ytop - 1.70,
+ dataset[1][0] == winner)
return VGroup(t, b1, b2)
def construct(self):
self.prepare()
- chip = self.chip("Estadística que engaña", ROSA)
+ chip = self.chip("Estadística que engaña", C_PINK)
with self.beat(0) as b:
b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.45)
- cab = VGroup(
+ header = VGroup(
self.fit(Text("dos tratamientos", font=FONT, font_size=52,
weight=BOLD, color=WHITE), 8.2),
VGroup(
- Text("A", font=FONT, font_size=90, weight=BOLD, color=CELESTE),
- Text("vs", font=FONT, font_size=44, color=GRIS),
- Text("B", font=FONT, font_size=90, weight=BOLD, color=ROSA),
+ Text("A", font=FONT, font_size=90, weight=BOLD, color=C_SKY),
+ Text("vs", font=FONT, font_size=44, color=C_GRAY),
+ Text("B", font=FONT, font_size=90, weight=BOLD, color=C_PINK),
).arrange(RIGHT, buff=0.7),
).arrange(DOWN, buff=0.45).move_to(UP * 3.0)
- b.play(FadeIn(cab[0], shift=UP * 0.15), run_time=0.6)
- b.play(FadeIn(cab[1][0], scale=0.6), run_time=0.35)
- b.play(FadeIn(cab[1][1]), run_time=0.2)
- b.play(FadeIn(cab[1][2], scale=0.6), run_time=0.35)
+ b.play(FadeIn(header[0], shift=UP * 0.15), run_time=0.6)
+ b.play(FadeIn(header[1][0], scale=0.6), run_time=0.35)
+ b.play(FadeIn(header[1][1]), run_time=0.2)
+ b.play(FadeIn(header[1][2], scale=0.6), run_time=0.35)
- lev = self.bloque("casos LEVES", LEV, 2.55, "A")
+ lever = self.block_obj("casos LEVES", LEVER, 2.55, "A")
with self.beat(1) as b:
- b.play(cab.animate.scale(0.5).move_to(UP * 5.4), run_time=0.5)
- b.play(FadeIn(lev[0], shift=RIGHT * 0.2), run_time=0.4)
- for bb in (lev[1], lev[2]):
+ b.play(header.animate.scale(0.5).move_to(UP * 5.4), run_time=0.5)
+ b.play(FadeIn(lever[0], shift=RIGHT * 0.2), run_time=0.4)
+ for bb in (lever[1], lever[2]):
b.play(FadeIn(bb[0]), FadeIn(bb[1]),
GrowFromEdge(bb[2], LEFT), FadeIn(bb[3]), run_time=0.55)
- gra = self.bloque("casos GRAVES", GRA, -0.35, "A")
+ grav = self.block_obj("casos GRAVES", GRAV_FIELD, -0.35, "A")
with self.beat(2) as b:
- b.play(FadeIn(gra[0], shift=RIGHT * 0.2), run_time=0.4)
- for bb in (gra[1], gra[2]):
+ b.play(FadeIn(grav[0], shift=RIGHT * 0.2), run_time=0.4)
+ for bb in (grav[1], grav[2]):
b.play(FadeIn(bb[0]), FadeIn(bb[1]),
GrowFromEdge(bb[2], LEFT), FadeIn(bb[3]), run_time=0.55)
- def tilde(col=VERDE):
+ def tilde(col=C_GREEN):
m = VMobject(stroke_color=col, stroke_width=9)
m.set_points_as_corners([[-0.20, 0.02, 0], [-0.05, -0.18, 0], [0.24, 0.26, 0]])
return m
with self.beat(3) as b:
tick = VGroup(*[tilde() for _ in range(2)])
- tick[0].next_to(lev[1][3], RIGHT, buff=0.25)
- tick[1].next_to(gra[1][3], RIGHT, buff=0.25)
+ tick[0].next_to(lever[1][3], RIGHT, buff=0.25)
+ tick[1].next_to(grav[1][3], RIGHT, buff=0.25)
b.play(FadeIn(tick[0], scale=0.5), run_time=0.4)
b.play(FadeIn(tick[1], scale=0.5), run_time=0.4)
- pre = self.fit(Text("A gana 2 de 2", font=FONT, font_size=48,
- weight=BOLD, color=CELESTE), 8.0).move_to(DOWN * 2.80)
- b.play(FadeIn(pre, shift=UP * 0.15), run_time=0.5)
+ pre_frames = self.fit(Text("A gana 2 de 2", font=FONT, font_size=48,
+ weight=BOLD, color=C_SKY), 8.0).move_to(DOWN * 2.80)
+ b.play(FadeIn(pre_frames, shift=UP * 0.15), run_time=0.5)
- tot = self.bloque("TODOS juntos", TOT, 2.55, "B")
+ tot = self.block_obj("TODOS juntos", TOT, 2.55, "B")
with self.beat(4) as b:
- b.play(FadeOut(VGroup(lev, gra, tick, pre)), run_time=0.45)
+ b.play(FadeOut(VGroup(lever, grav, tick, pre_frames)), run_time=0.45)
b.play(FadeIn(tot[0], shift=RIGHT * 0.2), run_time=0.4)
for bb in (tot[1], tot[2]):
b.play(FadeIn(bb[0]), FadeIn(bb[1]),
GrowFromEdge(bb[2], LEFT), FadeIn(bb[3]), run_time=0.6)
with self.beat(5) as b:
- b.play(Circumscribe(tot[2], color=VERDE, buff=0.18, stroke_width=6),
+ b.play(Circumscribe(tot[2], color=C_GREEN, buff=0.18, stroke_width=6),
run_time=0.8)
g = self.fit(Text("gana B", font=FONT, font_size=70, weight=BOLD,
- color=ROSA), 8.0).move_to(DOWN * 0.75)
+ color=C_PINK), 8.0).move_to(DOWN * 0.75)
ne = self.fit(Text("y no hay ningún error", font=FONT, font_size=44,
weight=BOLD, color=WHITE), 8.0).next_to(g, DOWN, buff=0.4)
b.play(FadeIn(g, scale=0.7), run_time=0.6)
b.play(FadeIn(ne, shift=UP * 0.15), run_time=0.5)
with self.beat(6) as b:
- b.play(FadeOut(VGroup(tot, g, ne, cab)), run_time=0.4)
- nom = VGroup(
+ b.play(FadeOut(VGroup(tot, g, ne, header)), run_time=0.4)
+ nm_key = VGroup(
self.fit(Text("PARADOJA", font=FONT, font_size=72, weight=BOLD,
- color=AMBAR), 8.2),
+ color=AMBER), 8.2),
self.fit(Text("DE SIMPSON", font=FONT, font_size=72, weight=BOLD,
- color=AMBAR), 8.2),
+ color=AMBER), 8.2),
).arrange(DOWN, buff=0.2).move_to(UP * 2.6)
- b.play(FadeIn(nom, scale=0.75), run_time=0.8)
- b.play(Flash(nom, color=AMBAR, line_length=0.6, num_lines=20,
+ b.play(FadeIn(nm_key, scale=0.75), run_time=0.8)
+ b.play(Flash(nm_key, color=AMBER, line_length=0.6, num_lines=20,
flash_radius=3.0), run_time=0.7)
- def reparto(letra, col, leves, graves, y):
- lab = Text(letra, font=FONT, font_size=50, weight=BOLD, color=col)
+ def split_up(letter, col, minor, graves, y):
+ lab = Text(letter, font=FONT, font_size=50, weight=BOLD, color=col)
lab.move_to([-3.65, y, 0])
- n = leves + graves
- wl = leves / n * BARW
+ n = minor + graves
+ wl = minor / n * BARW
a = Rectangle(width=max(wl, 0.05), height=0.7, stroke_width=0,
- fill_color=VERDE, fill_opacity=1).move_to([XL, y, 0], LEFT)
+ fill_color=C_GREEN, fill_opacity=1).move_to([XL, y, 0], LEFT)
c = Rectangle(width=max(BARW - wl, 0.05), height=0.7, stroke_width=0,
- fill_color=ROSA, fill_opacity=1).next_to(a, RIGHT, buff=0)
- nl = Text(str(leves), font=FONT, font_size=30, weight=BOLD, color="#0B0F1A").move_to(a)
+ fill_color=C_PINK, fill_opacity=1).next_to(a, RIGHT, buff=0)
+ nl = Text(str(minor), font=FONT, font_size=30, weight=BOLD, color="#0B0F1A").move_to(a)
ng = Text(str(graves), font=FONT, font_size=30, weight=BOLD, color="#0B0F1A").move_to(c)
return VGroup(lab, a, c, nl, ng)
- leyenda = VGroup(
- VGroup(Square(0.34, stroke_width=0, fill_color=VERDE, fill_opacity=1),
+ legend = VGroup(
+ VGroup(Square(0.34, stroke_width=0, fill_color=C_GREEN, fill_opacity=1),
Text("leves", font=FONT, font_size=32, color=WHITE)).arrange(RIGHT, buff=0.18),
- VGroup(Square(0.34, stroke_width=0, fill_color=ROSA, fill_opacity=1),
+ VGroup(Square(0.34, stroke_width=0, fill_color=C_PINK, fill_opacity=1),
Text("