오늘은 내가 임의로 설정하는 function을 지정해서 사용하는 방법이 핵심


def get_horizontal_line2graph(axes, function, x, width, color):
    result = VGroup()
    line = DashedLine(
        start = axes.c2p(0, function.underlying_function(x)),
        end   = axes.c2p(x, function.underlying_function(x)),
        stroke_width = width,
        stroke_color = color,
    )
    dot = Dot().set_color(color).move_to(axes.c2p(x, function.underlying_function(x)))
    result.add(line, dot)
    return result

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

        k = ValueTracker(-3)

        # Adding Mobjects for the first plane

        plane1 = NumberPlane(
            x_range=[-3,4,1], x_length=5,
            y_range=[-8,9,2], y_length=5
        ).add_coordinates().shift(LEFT * 3.5)

        func1 = plane1.plot(
            lambda x : (1/3)*x**3, x_range=[-3, 3], color=RED_C
        )

        func1_label = MathTex("f(x)=\\frac{1}{3}x^3").set(width=2.5)\
        .next_to(plane1, UP, buff=0.2).set_color(RED_C)

        moving_slope = always_redraw(lambda :
            plane1.get_secant_slope_group(
            graph = func1,
            x     = k.get_value(),
            dx    = 0.05,
            secant_line_length = 4,
            secant_line_color  = YELLOW)
            )
       
        dot = always_redraw(lambda :
                            Dot().move_to(
            plane1.c2p(k.get_value(), func1.underlying_function(k.get_value()))
                    )
                )
       
        # Plane2
        plane2 = NumberPlane(x_range=[-3,4,1], x_length=5,
                             y_range=[0,11,2], y_length=5).add_coordinates().shift(RIGHT * 3.5)
       
        func2 = always_redraw(lambda : plane2.plot(
            lambda x : x **2, x_range=[-3, k.get_value()], color=GREEN,
            )
        )

        func2_label = MathTex("f'(x)=x^2").set(width=2.5)\
        .next_to(plane2, UP, buff=0.2).set_color(GREEN)

        moving_h_line = always_redraw(
            lambda : get_horizontal_line2graph(
                axes=plane2, function=func2, x = k.get_value(),
                width=4, color=YELLOW
            )
        )

        slope_value_text = (
            Tex("slope value : ")
            .next_to(plane1, DOWN, buff=0.1)
            .set_color(YELLOW)
            .add_background_rectangle()
        )

        slope_value = always_redraw(
            lambda : DecimalNumber(num_decimal_places=4)
            .set_value(func2.underlying_function(k.get_value()))
            .next_to(slope_value_text, RIGHT, buff=0.1)
            .set_color(YELLOW)
            .add_background_rectangle()
        )

        self.play(
            LaggedStart(
                DrawBorderThenFill(plane1),
                DrawBorderThenFill(plane2),
                Create(func1),
                Write(func1_label),
                Write(func2_label),
                run_time=5,
                lag_ratio=0.5
            )
        )

        self.play(FadeIn(moving_slope, moving_h_line, func2, slope_value, slope_value_text, dot))
        self.wait(2)

        self.play(k.animate.set_value(3), run_time=10, rate_func=smooth)
        self.wait(4)



오늘은 나만의 새로운 def를 생성해보고 사용해보는 과정이 핵심이다. Manim이라고 해봐야 어쨋든 python library이고 python 기본 문법은 그대로 사용한다.


따라서 def를 통한 함수 생성도 완전히 동일한 방식으로 진행하면 된다.


  • DashedLine() class를 이용해서 점선을 만들 수 있다.
  • Dot() class를 이용해 점을 찍을 수 있다. 
  • 특정 function을 지정했다면, function.underlying_function(x) 메소드를 이용해서 그 함수의 x값을 지정해서 f(x)값을 얻어올 수 있다. 아주 유용한 기능이니 반드시 기억하자.
  • result에 VGroup으로 묶어서 만든 line과 dot을 전달한다.
  • ValueTracker 기능은 이전에도 설명했지만, Updator 기능을 적용하기 위해 필요한 class이다. Manim에서 아주, 아주 핵심적으로 사용되는 class이니 반드시 사용법을 익혀야 한다.
  • 특히 ValueTracker는 .get_value()와 .animate.set_value() 기능과 단짝처럼 사용된다. 기능은 이름 그대로이다.
  • NumberPlane() class를 이용해서 좌표평면계를 그릴 수 있다.
  • NumberPlane.plot(lambda x : YOUR FUNCTION) 메서드를 이용해서 생성한 특정 numberplane 위에 그래프를 그릴 수 있다. (예전에는 get_graph 메서드였는데 plot으로 변경됨)
  • MathTex는 LaTex기반으로 수식을 나타낼 때 사용하는 class이다. LaTex 문법을 알아야 사용 가능하다.
  • always_redraw(lambda : YOUR Mobject) 기능을 통해서 특정 Mobject의 animate를 Update할 수 있다. ValueTracker와 함께 아주 유용하게 사용되니 사용법을 반드시 익혀야 할 함수중의 하나이다.
  • moving_slope에는 get_secant_slope_group이라는 메서드가 저장되는데 이것은 어떤 그래프위에서 두 점사이의 평균 변화율 (기울기)을 plot하는 메서드이다. 사용법은 plane.get_secant_slope_group() 내부에서 특히 plane위의 특정한 graph를 지정하고, x값을 전달하면 x부터 dx만큼 떨어진 위치의 dy를 이용해 기울기를 그린다. 
  • 따라서 dx값을 0.01처럼 아주 작은값으로 설정하면 접선에서의 기울기 (= 미분계수 = 도함수)를 plot할 수 있고, dx값을 1처럼 크게 잡으면 평균 변화율을 plot 할 수 있다. 이것은 그냥 dx를 직접 바꿔보면서 실행해보는게 이해가 빠를 듯
  • moving_h_line 변수에는 우리가 직접 지정한 get_horizontal_line2graph함수가 저장되었다. 실행결과를 참고하면 get_horizontal_line2graph함수의 기능이 눈에 보일 것이다.
  • DecimalNumber는 표면적으로는 십진수라는 뜻이지만 대략 python의 Float와 비슷한 type의 class라고 생각하면 될 것 같다. num_decimal_places는 소수점 이하를 n자리 까지 나타내겠다는 의미이다.
  • LaggedStart()를 이용해서 약간씩의 delay를 준 상태로 애니메이션을 시작할 수 있다.
  • ValueTracker.animate.set_value(n)을 통해서 기존의 ValueTracker의 값을 n으로 바꿀 수 있다. 이때 변화하는 속도를 상당히 다양하게 지정할 수 있는데 그것은 아래 사이트를 참고하자
  • https://docs.manim.community/en/stable/reference/manim.utils.rate_functions.html

09b8c22ff3d32caf78bac5fb11d8221de162890ab747ea6e106a0ba9


실행결과