나의 작은 valley

[시각화 기술] Manim Community - Quickstart 본문

그래픽스(graphics)/시각화 기술(visualization)

[시각화 기술] Manim Community - Quickstart

붕옥 아이젠 2022. 11. 15. 17:14
728x90

글을 시작하기 앞서서 아래의 나올 코드들을 실제로 따라해보시려면 주피터 노트북을 사용하셔야 됩니다. 또한
%%manim - qh Class 이름 이라는 명령어가 코드에 첫 줄에 위치해야만 <<(이거 중요함 ㄹㅇ) 제대로 실행이 됩니다.



모든 것에 시작 후후.....

from manim import *

config.media_width = "0%"
config.verbosity = "WARNING"



간단한 벡터 모형

%%manim -qh VectorArrow
config.media_width = "20%"


class VectorArrow(Scene):
    def construct(self):
        dot = Dot(ORIGIN)
        arrow = Arrow(ORIGIN, [2, 2, 0], buff=0)
        numberplane = NumberPlane()
        origin_text = Text('(0, 0)').next_to(dot, DOWN)
        tip_text = Text('(2, 2)').next_to(arrow.get_end(), RIGHT)
        self.add(numberplane, dot, arrow, origin_text, tip_text)




삼각함수

%%manim -qh SineCurveUnitCircle

class SineCurveUnitCircle(Scene):
    # contributed by heejin_park, https://infograph.tistory.com/230
    def construct(self):
        self.show_axis()
        self.show_circle()
        self.move_dot_and_draw_curve()
        self.wait()

    def show_axis(self):
        x_start = np.array([-6,0,0])
        x_end = np.array([6,0,0])

        y_start = np.array([-4,-2,0])
        y_end = np.array([-4,2,0])

        x_axis = Line(x_start, x_end)
        y_axis = Line(y_start, y_end)

        self.add(x_axis, y_axis)
        self.add_x_labels()

        self.origin_point = np.array([-4,0,0])
        self.curve_start = np.array([-3,0,0])

    def add_x_labels(self):
        x_labels = [
            MathTex("\pi"), MathTex("2 \pi"),
            MathTex("3 \pi"), MathTex("4 \pi"),
        ]

        for i in range(len(x_labels)):
            x_labels[i].next_to(np.array([-1 + 2*i, 0, 0]), DOWN)
            self.add(x_labels[i])

    def show_circle(self):
        circle = Circle(radius=1)
        circle.move_to(self.origin_point)
        self.add(circle)
        self.circle = circle

    def move_dot_and_draw_curve(self):
        orbit = self.circle
        origin_point = self.origin_point

        dot = Dot(radius=0.08, color=YELLOW)
        dot.move_to(orbit.point_from_proportion(0))
        self.t_offset = 0
        rate = 0.25

        def go_around_circle(mob, dt):
            self.t_offset += (dt * rate)
            # print(self.t_offset)
            mob.move_to(orbit.point_from_proportion(self.t_offset % 1))

        def get_line_to_circle():
            return Line(origin_point, dot.get_center(), color=BLUE)

        def get_line_to_curve():
            x = self.curve_start[0] + self.t_offset * 4
            y = dot.get_center()[1]
            return Line(dot.get_center(), np.array([x,y,0]), color=YELLOW_A, stroke_width=2 )


        self.curve = VGroup()
        self.curve.add(Line(self.curve_start,self.curve_start))
        def get_curve():
            last_line = self.curve[-1]
            x = self.curve_start[0] + self.t_offset * 4
            y = dot.get_center()[1]
            new_line = Line(last_line.get_end(),np.array([x,y,0]), color=YELLOW_D)
            self.curve.add(new_line)

            return self.curve

        dot.add_updater(go_around_circle)

        origin_to_circle_line = always_redraw(get_line_to_circle)
        dot_to_curve_line = always_redraw(get_line_to_curve)
        sine_curve_line = always_redraw(get_curve)

        self.add(dot)
        self.add(orbit, origin_to_circle_line, dot_to_curve_line, sine_curve_line)
        self.wait(8.5)

        dot.remove_updater(go_around_circle)




<QuickStart>
=> Basic model

%%manim -qh CreateCircle

class CreateCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency
        self.play(Create(circle))

\

# from manim import * , (*)은 전부 !!
from manim import Scene
from manim import Circle
from manim import Create

%%manim -qh CreateCircle

class CreateCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        #circle.set_fill(PINK, opacity=2)  # opacity = 불투명도 1.0~0.0
        self.play(Create(circle))


# 상속 (Inheritance)
class MotherClass:
    def method_super(self):
        print("Super method")


# 괄호로 상속받을 클래스 이름 추가
class SonClass(MotherClass):
    pass



상속 여부 확인

print(issubclass(CreateCircle, Scene))
print(issubclass(Scene, CreateCircle))




상속의 필요성

class Animal:
    def walk(self):
        print("걸어간다.")

class Dog(Animal):
    def speak(self):
        print("왕왕")
class Duck(Animal):
    def speak(self):
        print("꽥꽥")


duck1 = Duck()
dog1 = Dog()

duck1.walk() 
dog1.walk() 

# Doh is an animal >> is-a >> is-a relationship


class Teacher:
    def teach(self):
        print("teaching")

class Student:
    def study(self):
        print("studing")

class Lesson:
    def __init__(self):
        self.teacher = Teacher()    #상속을 받지 않고 Class 객체를 만듬
        self.student = Student()
    
    def run(self):
        self.teacher.teach()
        self.student.study()



l = Lesson()
l.run()

# Lesson have student and teacher >> 일반적으로 has - a >> has-a relationship



# TMI 다중 상속
class A:
    def __init__(self):
        print("A")


class B:
    def __init__(self):
        print("B")


class C(A, B):
    def __init__(self):
        super().__init__()  #A의 init 매써드만 호출이 됨. 왠지는 몰?루
        #A.__init__(self)
        #B.__init__(self)
        print("C")
c = C()




# 엄마가 좋아 아빠가 좋아?
class A:
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        print("B in")
        super().__init__()
        print("B out")

class C(A):
    def __init__(self):
        print("C in")
        super().__init__()
        print("C out")

class D(B,C):
    def __init__(self):
        print("D in")
        super().__init__()
        print("D out")
        
d = D()




MRO 확인법

print(D.mro())  # MRO 확인, Method Resolution Order
<object 클래스>

모든 클래스는 object 클래스의 하위 클래스이다. 따라서 생략이 가능하다.
--------------------------------------------------------------------------------------------------------------------


먼 길로 돌아왔는데 결국

circle = Circle() << Circle이라는 클래스를 객체로 받음


circle.set_fill(PINK, opacity = 0.5) << 클래스 안에 있는 함수들




# Transforming a square into a circle
%%manim -qh SquareToCircle


class SquareToCircle(Scene):
    def construct(self):
        square = Square()  # create a square
        square.rotate(PI/4)  # rotate a certain amount
                             #아마 맨 아래 꼭짓점을 원점으로 생각하소 pie/4 정도 옮긴느낌
                             #잘 모르겠다....
        
        self.play(Create(square))  # animate the creation of the square

%%manim -qh SquareToCircle

class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set color and transparency

        square = Square()  # create a square
        square.rotate(PI / 4)  # rotate a certain amount

        self.play(Create(square))  # animate the creation of the square
        self.play(Transform(square, circle))  # interpolate the square into the circle
        self.play(FadeOut(circle))

%%manim -qh SquareToCircle

class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set color and transparency

        square = Square()  # create a square
        square.rotate(PI / 4)  # rotate a certain amount

        self.play(Create(square))  # animate the creation of the square
        self.play(Transform(square, circle))  # interpolate the square into the circle
        self.play(FadeOut(square) )




# Positioning
 
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=1)  # set the position
        self.play(Create(circle), Create(square))  # show the shapes on screen


%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=0)  # set the position
        self.play(Create(circle), Create(square))



%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=5)  # set the position 
                                               # 5cm보다는 쪼금 큰데? 인치는 확실히 너무 아니고 ...    
                                               #  ToDO: RIGHT, LEFT, UP, DOWN
        self.play(Create(circle), Create(square))




# Transforming a square into a circle
 
%%manim -qh SquareToCircle


class SquareToCircle(Scene):
    def construct(self):
        square = Square()  # create a square
        square.rotate(PI/4)  # rotate a certain amount
                             #아마 맨 아래 꼭짓점을 원점으로 생각하소 pie/4 정도 옮긴느낌
                             #잘 모르겠다....
        
        self.play(Create(square))  # animate the creation of the square
%%manim -qh SquareToCircle

class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set color and transparency

        square = Square()  # create a square
        square.rotate(PI / 4)  # rotate a certain amount

        self.play(Create(square))  # animate the creation of the square
        self.play(Transform(square, circle))  # interpolate the square into the circle
        self.play(FadeOut(square) )




# Positioning

%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=1)  # set the position
        self.play(Create(circle), Create(square))  # show the shapes on screen
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=0)  # set the position
        self.play(Create(circle), Create(square))
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=5)  # set the position 
                                               # 5cm보다는 쪼금 큰데? 인치는 확실히 너무 아니고 ...    
                                               #  ToDO: RIGHT, LEFT, UP, DOWN
        self.play(Create(circle), Create(square))




# Transforming a square into a circle
%%manim -qh SquareToCircle


class SquareToCircle(Scene):
    def construct(self):
        square = Square()  # create a square
        square.rotate(PI/4)  # rotate a certain amount
                             #아마 맨 아래 꼭짓점을 원점으로 생각하소 pie/4 정도 옮긴느낌
                             #잘 모르겠다....
        
        self.play(Create(square))  # animate the creation of the square
%%manim -qh SquareToCircle

class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set color and transparency

        square = Square()  # create a square
        square.rotate(PI / 4)  # rotate a certain amount

        self.play(Create(square))  # animate the creation of the square
        self.play(Transform(square, circle))  # interpolate the square into the circle
        self.play(FadeOut(circle))
%%manim -qh SquareToCircle

class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set color and transparency

        square = Square()  # create a square
        square.rotate(PI / 4)  # rotate a certain amount

        self.play(Create(square))  # animate the creation of the square
        self.play(Transform(square, circle))  # interpolate the square into the circle
        self.play(FadeOut(square) )



# Positioning
 
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=1)  # set the position
        self.play(Create(circle), Create(square))  # show the shapes on screen
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=0)  # set the position
        self.play(Create(circle), Create(square))
%%manim -qh SquareAndCircle

class SquareAndCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        circle.set_fill(PINK, opacity=0.5)  # set the color and transparency

        square = Square()  # create a square
        square.set_fill(BLUE, opacity=0.5)  # set the color and transparency

        square.next_to(circle, RIGHT, buff=5)  # set the position 
                                               # 5cm보다는 쪼금 큰데? 인치는 확실히 너무 아니고 ...    
                                               #  ToDO: RIGHT, LEFT, UP, DOWN
        self.play(Create(circle), Create(square))



# Using .animate syntax to animate methods
%%manim -qh AnimatedSquareToCircle
class AnimatedSquareToCircle(Scene):
    def construct(self):
        circle = Circle()  # create a circle
        square = Square()  # create a square

        self.play(Create(square))  # show the square on screen
        self.play(square.animate.rotate(PI / 4))  # rotate the square
        self.play(
            ReplacementTransform(square, circle)
        )  # transform the square into a circle
        self.play(
            circle.animate.set_fill(PINK, opacity=0.5)
        )  # color the circle on screen

        # being applied to the Mobject dynamically, instead of creating them with the changes already applied.
%%manim -qh DifferentRotations

class DifferentRotations(Scene):
    def construct(self):
        left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
        right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
        self.play(
            left_square.animate.rotate(PI), 
            Rotate(right_square, angle=PI), 
            run_time=2
        )
        self.wait()
왼쪽에 있는 사각형은 회전이라기 보다는 축소, 오른쪽에 있는 사각형이 좀 더 회전이라는 말에 적합해 보인다.
 
 
 
 
 
%%manim -qh DifferentRotations
class DifferentRotations(Scene):
    def construct(self):
        left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
        right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
        self.play(
            left_square.animate.rotate(PI/4), 
            Rotate(right_square, angle=PI), 
            run_time=2
        )
        self.wait()

%%manim -qh DifferentRotations
class DifferentRotations(Scene):
    def construct(self):
        left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
        right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
        self.play(
            left_square.animate.rotate(PI/2), 
            Rotate(right_square, angle=PI), 
            run_time=2
        )
        self.wait()
%%manim -qh DifferentRotations
class DifferentRotations(Scene):
    def construct(self):
        left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
        right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
        self.play(
            left_square.animate.rotate(PI*(9/4)), 
            Rotate(right_square, angle=PI), 
            run_time=2
        )
        self.wait()
.animate’s interpretation of rotation 이 의미하는 바는 알겠는데 어느정도 축소될지가 어떻게 정해지는 것인지는 모르겠다 !! 
 
 
 
728x90
Comments