aboutsummaryrefslogtreecommitdiffstats
path: root/scenes/v13_cuerda.py
blob: c02ea1cac3b4d4117b0eaeced82278a55893628c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# -*- coding: utf-8 -*-
import sys, os, math
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from manim import *
from tiktok import *

CTR = UP * 1.75
RT = 2.05           # Earth radius on screen
GAP_W = 0.72        # drawn gap (exaggerated)


def cat(h=0.55, color="#E8EDF7"):
    """Simple cat silhouette in profile, total height = h."""
    body = Ellipse(width=0.90, height=0.34, stroke_width=0, fill_color=color,
                   fill_opacity=1).move_to([0, 0.12, 0])
    head = Circle(radius=0.17, stroke_width=0, fill_color=color,
                  fill_opacity=1).move_to([0.46, 0.26, 0])
    e1 = Triangle(stroke_width=0, fill_color=color, fill_opacity=1).scale(0.09)
    e1.move_to([0.39, 0.42, 0])
    e2 = e1.copy().shift(RIGHT * 0.15)
    tail = ArcBetweenPoints([-0.44, 0.16, 0], [-0.62, 0.52, 0], angle=-1.6,
                            stroke_width=5, color=color)
    legs = VGroup(*[Line([x, 0.02, 0], [x, -0.16, 0], stroke_width=6, color=color)
                    for x in (-0.28, -0.08, 0.18, 0.36)])
    g = VGroup(tail, body, legs, head, e1, e2)
    g.scale(h / g.height)
    return g


class Rope(TikTok):
    NAME = "cuerda"

    def planet(self, r, center, col="#1D3B6E"):
        p = Circle(radius=r, stroke_width=4, stroke_color=C_SKY,
                   fill_color=col, fill_opacity=1).move_to(center)
        return p

    def construct(self):
        self.prepare()
        chip = self.chip("Intuición rota", C_SKY)

        earth = self.planet(RT, CTR)
        rope = Circle(radius=RT + 0.03, stroke_width=7, color=AMBER).move_to(CTR)

        with self.beat(0) as b:
            b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.45)
            b.play(GrowFromCenter(earth), run_time=0.7)
            b.play(Create(rope), run_time=max(0.8, b.floor - 1.6))

        with self.beat(1) as b:
            km = Text("40.000 km", font=FONT, font_size=50, weight=BOLD, color=AMBER)
            km.move_to(CTR + DOWN * 0.0)
            box = RoundedRectangle(corner_radius=0.16, stroke_width=0, fill_color="#0B0F1A",
                                   fill_opacity=0.78, width=km.width + 0.5,
                                   height=km.height + 0.35).move_to(km)
            b.play(FadeIn(VGroup(box, km), scale=0.7), run_time=0.8)

        with self.beat(2) as b:
            b.play(FadeOut(VGroup(box, km)), run_time=0.3)
            seg_m = Line(LEFT * 0.6, RIGHT * 0.6, stroke_width=9, color=C_GREEN)
            tip = VGroup(*[Line(UP * 0.16, DOWN * 0.16, stroke_width=6, color=C_GREEN)
                           .move_to(p) for p in (seg_m.get_start(), seg_m.get_end())])
            lab = Text("+ 1 metro", font=FONT, font_size=48, weight=BOLD, color=C_GREEN)
            g = VGroup(VGroup(seg_m, tip), lab).arrange(DOWN, buff=0.3).move_to(DOWN * 2.15)
            b.play(GrowFromCenter(VGroup(seg_m, tip)), run_time=0.5)
            b.play(FadeIn(lab, shift=UP * 0.15), run_time=0.6)

        with self.beat(3) as b:
            high_c = Circle(radius=RT + GAP_W, stroke_width=7, color=AMBER).move_to(CTR)
            radios = VGroup(*[
                DashedLine(CTR + RT * np.array([math.cos(a), math.sin(a), 0]),
                           CTR + (RT + GAP_W) * np.array([math.cos(a), math.sin(a), 0]),
                           stroke_width=4, color="#7C8AA8", dash_length=0.07)
                for a in np.linspace(0, TAU, 16, endpoint=False)])
            b.play(FadeOut(g), run_time=0.25)
            b.play(Transform(rope, high_c), run_time=1.0)
            b.play(FadeIn(radios), run_time=0.5)
            scale_f = Text("(dibujo exagerado)", font=FONT, font_size=28, color=C_GRAY)
            scale_f.move_to(DOWN * 2.6)
            b.play(FadeIn(scale_f), run_time=0.35)

        with self.beat(4) as b:
            q = VGroup(
                self.fit(Text("¿cuánto se separa?", font=FONT, font_size=52,
                              weight=BOLD, color=WHITE), 8.0),
                VGroup(
                    Text("«nada»", font=FONT, font_size=40, color=C_GRAY),
                    Text("«un pelo»", font=FONT, font_size=40, color=C_GRAY),
                ).arrange(RIGHT, buff=0.7),
            ).arrange(DOWN, buff=0.35).move_to(CTR)
            bx = RoundedRectangle(corner_radius=0.2, stroke_width=0, fill_color="#0B0F1A",
                                  fill_opacity=0.82, width=q.width + 0.6,
                                  height=q.height + 0.5).move_to(q)
            b.play(FadeIn(VGroup(bx, q), scale=0.85), run_time=0.8)

        with self.beat(5) as b:
            b.play(FadeOut(VGroup(bx, q)), run_time=0.3)
            gt = cat(GAP_W * 0.92).move_to(CTR + UP * (RT + GAP_W / 2))
            med = DoubleArrow(CTR + LEFT * RT, CTR + LEFT * (RT + GAP_W), buff=0,
                              color=C_GREEN, stroke_width=6, tip_length=0.18)
            val = Text("15,9 cm", font=FONT, font_size=42, weight=BOLD, color=C_GREEN)
            val.next_to(med, UP, buff=0.22)
            b.play(GrowArrow(med), FadeIn(val), run_time=0.7)
            b.play(FadeIn(gt, shift=RIGHT * 0.3), run_time=0.7)

        with self.beat(6) as b:
            b.play(FadeOut(VGroup(radios, gt, med, val, scale_f)), run_time=0.4)
            b.play(VGroup(earth, rope).animate.scale(0.52).move_to(UP * 4.6),
                   run_time=0.6)
            f1 = MathTex(r"r = \frac{P}{2\pi}", color=WHITE).scale(1.6).move_to(UP * 1.5)
            b.play(Write(f1), run_time=1.0)

        with self.beat(7) as b:
            f2 = MathTex(r"\Delta r = \frac{1\,\text{m}}{2\pi}", color=AMBER)
            f2.scale(1.6).move_to(DOWN * 0.5)
            b.play(Write(f2), run_time=1.1)

        with self.beat(8) as b:
            f3 = MathTex(r"= 0{,}159\ \text{m} = 15{,}9\ \text{cm}", color=C_GREEN)
            f3.scale(1.25).move_to(DOWN * 2.15)
            b.play(Write(f3), run_time=0.9)
            note_txt = self.fit(Text("el tamaño del planeta no aparece", font=FONT,
                                 font_size=40, weight=BOLD, color=C_PINK), 8.2)
            note_txt.move_to(DOWN * 3.05)
            b.play(FadeIn(note_txt, shift=UP * 0.15), run_time=0.6)

        with self.beat(9) as b:
            b.play(FadeOut(VGroup(f1, f2, f3, note_txt, earth, rope)), run_time=0.45)
            def pair_label(r, label, x, col):
                c0 = [x, 1.75, 0]
                p = self.planet(r, c0, col)
                c = Circle(radius=r + 0.30, stroke_width=6, color=AMBER).move_to(c0)
                lab = Text(label, font=FONT, font_size=36, weight=BOLD, color=WHITE)
                lab.move_to([x, -0.55, 0])
                v = Text("15,9 cm", font=FONT, font_size=38, weight=BOLD, color=C_GREEN)
                v.move_to([x, -1.25, 0])
                return VGroup(p, c, lab, v)
            left_lab = pair_label(1.25, "la Tierra", -2.05, "#1D3B6E")
            de = pair_label(0.55, "una pelota de tenis", 2.05, "#2F7A3C")
            self.fit(de[2], 3.9)
            b.play(FadeIn(left_lab), run_time=0.6)
            b.play(FadeIn(de), run_time=0.6)
            ig = Text("=", font=FONT, font_size=64, weight=BOLD, color=AMBER)
            ig.move_to([0, 1.75, 0])
            b.play(FadeIn(ig, scale=0.6), run_time=0.5)
            esc2 = Text("(no está a escala)", font=FONT, font_size=28, color=C_GRAY)
            esc2.move_to(DOWN * 2.35)
            b.play(FadeIn(esc2), run_time=0.35)

        with self.beat(10) as b:
            b.play(FadeOut(VGroup(left_lab, de, ig, esc2)), run_time=0.4)
            count_txt = VGroup(
                self.fit(Text("el tamaño no importa", font=FONT, font_size=56,
                              weight=BOLD, color=AMBER), 8.0),
                self.fit(Text("mandáselo al que dudó", font=FONT, font_size=44,
                              weight=BOLD, color=WHITE), 8.0),
            ).arrange(DOWN, buff=0.38).move_to(UP * 1.4)
            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()