Skip to article frontmatterSkip to article content
Números

Progressão Aritmética

Fundamentação

Código-fonte
main.py
from manim import *
from pathlib import Path
import os



class cena1(Scene):
    def construct(self):

        # ABERTURA DO VÍDEO
        inicio = Text("SAEPE Animado")
        fim = inicio.copy()
        triangulo = Triangle(color=BLUE)
        retangulo = Rectangle(width=2.5, height=1.5, color=GREEN)
        pentagono = RegularPolygon(n=5, radius=1, color=ORANGE)
        hexagono = RegularPolygon(n=6, radius=1, color=PURPLE)
        
        self.wait()
        self.play(Write(inicio))
        self.wait()
        self.play(Transform(
            inicio,
            fim.shift(2*UP),
            path_func=utils.paths.straight_path(),
            run_time=1.5,
        ))
        self.wait()

        triangulo.shift(LEFT * 4.5)
        retangulo.shift(LEFT * 1.6)
        pentagono.shift(RIGHT * 1.6)
        hexagono.shift(RIGHT * 4.5)

        self.play(Create(triangulo), Create(retangulo),
                  Create(pentagono), Create(hexagono))
        self.wait(1)

        # AGRUPAMENTO E REDUÇÃO DAS FIGURAS
        grupo1 = VGroup(triangulo, retangulo, pentagono, hexagono)
        self.play(grupo1.animate.scale(0.7))
        self.wait(0.5)

        for _ in range(4):
            self.play(CyclicReplace(*grupo1))
        self.wait(1)

        # Agora adiciona o texto e agrupa tudo
        titulo_gp = Text(
            "Números e Operações/Álgebra e Funções", font="Fira Sans").scale(0.75)
        titulo_gp.next_to(grupo1, DOWN, buff=0.8)

        self.play(Write(titulo_gp))
        self.wait(1)

        grupo_com_texto = VGroup(grupo1, titulo_gp, inicio)
        self.play(FadeOut(grupo_com_texto))
        t1 = Text("Progressão Aritmética", font="Fira Sans").scale(0.5)
        self.play(Write(t1, run_time=2))
        self.wait(0.5)

        linha = Line(
            start=t1.get_bottom() + DOWN * 0.2 + LEFT * t1.width / 2,
            end=t1.get_bottom() + DOWN * 0.2 + RIGHT * t1.width / 2,
            stroke_width=6,
        )
        linha.set_color(RED)

        # Função para atualizar a cor da linha
        def atualizar_linha(obj, dt):
            t = self.time
            nova_cor = interpolate_color(RED, BLUE, (np.sin(t * 2) + 1) / 2)
            obj.set_color(nova_cor)

        linha.add_updater(atualizar_linha)
        self.play(FadeIn(linha))
        self.wait(1)


        grupo2 = VGroup(linha, t1)
        self.play(grupo2.animate.scale(0.9).to_corner(UP + LEFT), run_time=1.5)
        self.wait(1.5)

        explicacao = Paragraph(
            r"As progressões aritméticas são sequências numéricas em que cada termo subsequente é obtido pela adição de uma constante.",
            r"Para exemplificar, considere a situação ilustrada com os quadrados abaixo.",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35)

        # Posiciona abaixo e alinha à esquerda com o grupo
        explicacao.next_to(grupo2, DOWN, buff=0.3)
        explicacao.align_to(grupo2, LEFT)  # <- ESSENCIAL!

        self.play(Write(explicacao, run_time = 1))
        self.wait(1)

        quadrados = VGroup(*[
            VGroup(
                Square(0.2*i).next_to(DOWN, UP, buff=0).shift(6*LEFT + 1.24**i*RIGHT + i*0.05*RIGHT),
                MathTex(f'{i}').scale(0.7).next_to(DOWN, DOWN, buff=0.3).shift(6*LEFT + 1.24**i*RIGHT + i*0.05*RIGHT),
            )
            for i in range(1, 8, 2)
        ]).add(Tex('...').next_to(DOWN, UP, buff=0)).shift(4.5*LEFT + 1.24**8*RIGHT + 8*0.05*RIGHT)

        self.play(Write(quadrados))
        
        self.play(quadrados.animate.shift(2*LEFT))


        explicacao1 = Paragraph(
            r"Nessa sequência, a diferença constante entre os lados é 2, que representa a razão da progressão.",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35)

        # Posiciona abaixo e alinha à esquerda com o grupo
        explicacao1.next_to(grupo2, DOWN, buff=5)
        explicacao1.align_to(grupo2, LEFT)  # <- ESSENCIAL!

        self.play(Write(explicacao1, run_time = 1))
        self.wait(1)




        explicacao_formula = Paragraph(
            r"Com isso, podemos escrever uma função que calcule o tamanho do lado do n-ésimo quadrado dessa progressão.",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35)

        # Posiciona abaixo e alinha à esquerda com o grupo
        explicacao_formula.next_to(grupo2, DOWN, buff=5.5)
        explicacao_formula.align_to(grupo2, LEFT)  # <- ESSENCIAL!

        self.play(Write(explicacao_formula, run_time = 1))
        self.wait(1)

        funcoes_exemplo = MathTex(r'f(1)=1\\f(2)=3\\f(3)=4\\f(4)=7').scale(0.7).shift(1.5*RIGHT + 0.2*DOWN)
        funcao = MathTex('f(n) = 1 + 2n').scale(0.7).shift(4*RIGHT + 0.5*DOWN)


    
        
        self.play(Write(funcoes_exemplo))
        self.play(Write(funcao))

         # --- Apaga todos os elementos visíveis com fade ---
        self.play(*[FadeOut(mob) for mob in self.mobjects])
        self.wait(0.5)


        duvida = Paragraph(
            r"Como podemos deduzir essa função?",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35)

        self.play(Write(duvida))
        self.wait(1.5)
        self.play(FadeOut(duvida))

        numeros = [
            Tex(f'{i}').scale(0.9).shift(2 * LEFT + i * 0.5 * RIGHT)
            for i in range(1, 8, 2)
        ]
        steps = [
            ArcBetweenPoints(start=start.get_center() + 0.05 * RIGHT,
                             end=end.get_center() + 0.1 * LEFT,
                             color=RED).shift(0.5 * DOWN)
            for start, end in zip(numeros[:-1], numeros[1:])
        ]
        steps_number = [
            Tex(f'+2', color=YELLOW).scale(0.8).next_to(steps[i], DOWN, buff=0.3).shift(0.05 * LEFT)
            for i in range(len(steps))
        ]
        visualizar = VGroup(*numeros, *steps, *steps_number)
        visualizar.shift(UP * 1.2)


        explicacao3 = Paragraph(
            r"A progressão começa em 1 e aumenta de 2 em 2. Para escrever a fórmula, precisamos do primeiro termo da progressão, no caso 1,",
            r"e da diferença entre dois termos, no caso 2. Com isso, podemos ter a seguinte fórmula. Usamos n-1 pois a progressão começa a ",
            r"partir da posição 0 em vez da 1.",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35).shift(UP*2.4)

    
        self.play(Write(explicacao3), run_time = 2)
        self.wait(1.5)


        self.play(Write(visualizar, run_time = 3))
        self.wait(1)

        self.play(visualizar.animate.shift(4.5 * LEFT), run_time = 1.5)



        formula = MathTex(r'f(n) = 1 + 2n').scale(0.7).shift(UP*1.1)
        self.play(Write(formula))

        

        formula_geral = MathTex(r'a_{n} = a_{1} + (n - 1) \cdot r').scale(0.7)
        self.play(Write(formula_geral))
        self.wait(1)

        termos = Tex(
            r'''
            \raggedright
            $a_n$: n-ésimo termo da progressão \\
            $a_1$: primeiro termo da progressão \\
            $n$: posição do termo na progressão \\
            $r$: razão
            '''
        ).scale(0.6).shift(1.2 * DOWN + 0.5*RIGHT)

        self.play(Write(termos))
        self.wait(1)

        self.play(*[FadeOut(mob) for mob in self.mobjects])
        self.wait(1.5)


        
        




        




        







        

    

Exercícios Resolvidos

Código-fonte
exercicio1.py
from manim import *
from pathlib import Path
import os

class cena1(Scene):
    def construct(self):


# --- Título com linha animada ---
        t5 = Text("Questão Progressão Aritmética (SAEPE - 2019)", font="Fira Sans").scale(0.5)
        self.play(Write(t5, run_time=2))
        self.wait(0.5)

        linha5 = Line(
            start=t5.get_bottom() + DOWN * 0.2 + LEFT * t5.width / 2,
            end=t5.get_bottom() + DOWN * 0.2 + RIGHT * t5.width / 2,
            stroke_width=6,
        )
        linha5.set_color(RED)

        def atualizar_linha5(obj, dt):
            tempo = self.time
            nova_cor = interpolate_color(RED, BLUE, (np.sin(tempo * 2) + 1) / 2)
            obj.set_color(nova_cor)

        linha5.add_updater(atualizar_linha5)
        self.play(FadeIn(linha5))
        self.wait(1)

        grupo_titulo5 = VGroup(t5, linha5)
        self.play(grupo_titulo5.animate.scale(0.9).to_corner(UL), run_time=1.5)
        self.wait(1)

        # --- Enunciado ---
        enunciado = Paragraph(
            "Em março de 2017, Taís começou a trabalhar como manicure e comprou 8 vidros de esmalte. Após isso, a cada mês, ela comprou",
            "2 vidros de esmalte a mais do que havia comprado no mês anterior. Em agosto de 2017, o preço de cada vidro de esmalte",
            "era R$ 3,75. A quantia gasta por Taís, em agosto de 2017, na compra desses vidros de esmalte foi:",
            alignment="left",
            line_spacing=0.8,
            font="CMU Serif"
        ).scale(0.35)

        enunciado.next_to(grupo_titulo5, DOWN, buff=0.3)
        enunciado.align_to(grupo_titulo5, LEFT)
        self.play(Write(enunciado, run_time=2))
        self.wait(1)

        formula_geral1 = MathTex(r'a_n = a_1 + (n - 1) \cdot r').scale(0.7)
        formula_geral1.next_to(enunciado, DOWN, buff=0.3)
        formula_geral1.align_to(enunciado, LEFT)
        self.play(Write(formula_geral1))
        self.wait(1)

        # --- Alternativas ---
        alternativas = VGroup(
            Tex("A) R\$ 37{,}50", font_size=24),
            Tex("B) R\$ 45{,}00", font_size=24),
            Tex("C) R\$ 52{,}50", font_size=24),
            Tex("D) R\$ 67{,}50", font_size=24),
            Tex("E) R\$ 75{,}00", font_size=24),
        ).arrange(DOWN, aligned_edge=LEFT)

        alternativas.next_to(enunciado, DOWN, buff=1.6).align_to(enunciado, LEFT)
        self.play(Write(alternativas))
        self.wait(1)

        # --- Resolução PARTE 1 ---
        parte1 = VGroup(
            MathTex(r"a_1 = 8", font_size=26),
            MathTex(r"r = 2", font_size=26),
            MathTex(r"n = 6", font_size=26, color=BLUE),
            MathTex(r"a_6 = 8 + (6 - 1) \cdot 2", font_size=26),
            MathTex(r"a_6 = 8 + 10 = 18", font_size=26),
        ).arrange(DOWN, aligned_edge=LEFT, buff=0.3)

        parte1.next_to(alternativas, RIGHT, buff=1)
        parte1.align_to(alternativas, UP)
        for linha in parte1:
            self.play(Write(linha))
            self.wait(0.5)

        # --- Resolução PARTE 2 ---
        parte2 = VGroup(
            MathTex(r"\text{Custo} = 18 \cdot 3{,}75", font_size=26),
            MathTex(r"\text{Custo} = 67{,}50", font_size=26),
            MathTex(r"\therefore\ \boxed{\text{R\$ 67{,}50}}", font_size=26, color=YELLOW),
        ).arrange(DOWN, aligned_edge=LEFT, buff=0.3)

        parte2.next_to(parte1, RIGHT, buff=1)
        parte2.align_to(parte1, UP)
        for linha in parte2:
            self.play(Write(linha))
            self.wait(0.5)

        # --- Destacar alternativa correta (letra D) ---
        alternativa_correta = alternativas[3]
        self.play(Circumscribe(alternativa_correta, color=YELLOW))
        self.play(Indicate(alternativa_correta, color=YELLOW))
        self.play(alternativa_correta.animate.set_color(YELLOW))
        self.wait(3)


Código-fonte
exercicio2.py
from manim import *

class cena(Scene):
    def construct(self):

        # Título centralizado
        titulo = Text("Questão Progressão Aritmética (SAEPE - 2021)", font="Fira Sans").scale(0.5)
        self.play(Write(titulo))
        self.wait(0.5)

        # Linha exatamente do tamanho do texto
        linha = Line(
            start=titulo.get_bottom() + DOWN * 0.2 + LEFT * titulo.width / 2,
            end=titulo.get_bottom() + DOWN * 0.2 + RIGHT * titulo.width / 2,
            stroke_width=6
        ).set_color(RED)

        # Atualizador de cor animada
        linha.add_updater(lambda m, dt: m.set_color(interpolate_color(RED, BLUE, (np.sin(self.time * 2) + 1) / 2)))
        self.play(FadeIn(linha))
        self.wait(0.5)

        # Agrupamento e movimento animado para o canto superior esquerdo
        grupo_titulo = VGroup(titulo, linha)
        self.play(grupo_titulo.animate.scale(0.9).to_corner(UL))
        self.wait(1)

        # Enunciado
        enunciado = Paragraph(
            r"Dentre os anos de 2000 e 2012, a exportação de uma fruta aumentou 5 000 toneladas a cada ano. Em 2010, a exportação foi",
            r"de 103 000 toneladas. Quantas toneladas foram exportadas no ano 2000?",
            alignment="left",
            line_spacing=0.8, 
            font="CMU Serif"
        ).scale(0.35).next_to(grupo_titulo, DOWN, aligned_edge=LEFT)

        self.play(Write(enunciado, run_time=2))
        self.wait(0.5)

        # Fórmula
        formula = MathTex(r"a_n = a_1 + (n - 1) \cdot r").scale(0.65)
        formula.next_to(enunciado, DOWN, buff=0.8).align_to(enunciado, LEFT)
        self.play(Write(formula))
        self.wait(0.5)

        # Alternativas
        alternativas = VGroup(
            Tex("A) 58 000", font_size=24),
            Tex("B) 53 000", font_size=24),
            Tex("C) 9 800", font_size=24),
            Tex("D) 7 923", font_size=24),
            Tex("E) 5 300", font_size=24),
        ).arrange(DOWN, aligned_edge=LEFT, buff=0.3)

        alternativas.next_to(formula, DOWN, buff=0.8).align_to(formula, LEFT)
        self.play(Write(alternativas))
        self.wait(1)

        

        # Resolução passo a passo
        passo1 = MathTex(r"a_{11} = 103\,000", font_size=26)
        passo2 = MathTex(r"a_1 + 10 \cdot 5\,000 = 103\,000", font_size=26)
        passo3 = MathTex(r"a_1 + 50\,000 = 103\,000", font_size=26)
        passo4 = MathTex(r"a_1 = 103\,000 - 50\,000", font_size=26)
        passo5 = MathTex(r"a_1 = 53\,000", font_size=26, color=YELLOW)

        passos = VGroup(passo1, passo2, passo3, passo4, passo5).arrange(DOWN, aligned_edge=LEFT, buff=0.3)
        passos.shift(RIGHT * 2.8 + DOWN * 1)

        for p in passos:
            self.play(Write(p))
            self.wait(0.4)


        # Destacar alternativa correta (letra B)
        alternativa_correta = alternativas[1]
        self.play(Circumscribe(alternativa_correta, color=YELLOW))
        self.play(Indicate(alternativa_correta, color=YELLOW))
        self.play(alternativa_correta.animate.set_color(YELLOW))
        self.wait(2)