Update the value of a function in Manim

Submitted by Jhun Vert on Tue, 11/10/2020 - 12:42

The code below will update the function V = 3(x - 6)2 as x increases in value. Notice that the equation is a parabolic curve with independent variable x and dependent variable V. The whole graph actually cannot be fitted on the screen. To improve visibility, the equation was multiplied by a reduction factor whose value is embedded-hard into the equation.

from manimlib.imports import *

class RedDot(Dot):
    CONFIG = {
        "fill_color": RED,
        "fill_opacity": 1,
        "stroke_color": YELLOW,
        "stroke_width": 1.7,
    }

class VolumeFunction(GraphScene):
    CONFIG = {
        "graph_origin": 3 * DOWN + 2.5 * LEFT,
        "x_min": -3,
        "x_max": 9,
        "x_axis_width": 12,
        "y_min": -1,
        "y_max": 7,
        "y_axis_label": "$V$",
        "y_axis_height": 8,
    }

    def construct(self):
        self.setup_axes()
        self.x_axis.remove(self.x_axis[1])
        self.y_axis.remove(self.y_axis[1])
        self.play(Write(self.axes))
        
        volume_function = lambda x: (6*x**2 - 36*x + 54)/25

        parabola_right = self.get_graph(
                volume_function,
                x_min = 3,
                x_max = 8,
                color = BLUE,
                stroke_width = 6
            )
   
        parabola_full = self.get_graph(
                volume_function,
                x_min = -3,
                x_max = 9,
                color = RED,
                stroke_width = 2
            )
        
        self.play(ShowCreation(parabola_full), run_time=3)
        self.wait()

        anim_kwargs = {"run_time":5,"rate_func":linear}
        self.move_dot_path(parabola_right,anim_kwargs)
        self.wait()
    
    def move_dot_path(self,parabola_right,anim_kwargs):
        parabola_right_copy = parabola_right.copy()
        dot_guide_p = RedDot(self.coords_to_point(3,0))
        dot_guide_x = RedDot(self.coords_to_point(3,0))
        dot_guide_y = RedDot(self.coords_to_point(0,0))
        line_x_p = DashedLine(dot_guide_x.get_center(),dot_guide_p.get_center())
        line_p_y = DashedLine(dot_guide_p.get_center(),dot_guide_y.get_center())
        dimX = DecimalNumber(
                6,
                num_decimal_places=2,
                include_sign=False,
                unit="\\rm cm",
                color=GREEN
            )
        dimV = DecimalNumber(
                0,
                num_decimal_places=2,
                include_sign=False,
                unit="\\rm cm^3",
                color=YELLOW
            )
        
        dimX.add_updater(lambda d: d.next_to(dot_guide_x, DOWN*0.2))
        dimX.add_updater(lambda d: d.set_value(5+2*dot_guide_x.get_center()[0]))
        dimV.add_updater(lambda e: e.next_to(dot_guide_y, 0.2*RIGHT+0.2*DOWN))
        dimV.add_updater(lambda e: e.set_value(150+50*dot_guide_y.get_center()[1]))

        group = VGroup(dot_guide_p,dot_guide_x,dot_guide_y,line_x_p,line_p_y)

        def update_group(group):
            p,x_p,p_y,ln_xp,ln_py = group
            p.move_to(dot_guide_p)
            x_p.move_to(self.coords_to_point(2.5+dot_guide_p.get_center()[0],0))
            p_y.move_to(self.coords_to_point(0,3+dot_guide_p.get_center()[1]))
            ln_xp.become(DashedLine(dot_guide_x.get_center(),dot_guide_p.get_center()))
            ln_py.become(DashedLine(dot_guide_p.get_center(),dot_guide_y.get_center()))

        group.add_updater(update_group)
        self.play(FadeIn(group))
        self.wait()

        self.play(Write(dimX))
        self.wait()

        self.play(Write(dimV))
        self.wait()

        self.bring_to_back(self.axes)
        
        self.play(
            MoveAlongPath(dot_guide_p,parabola_right_copy),
            ShowCreation(parabola_right),
            **anim_kwargs
        )

        group.clear_updaters()
        self.wait()

The implementation here is more advance than my way of coding. Much of the above code was lifted from the work of Theorem of Beethoven and was modified to cater my specific need.

Video output:

Category