이 글은
2022.09.22 - [분류 전체보기] - Manim. 도형 회전 rotate의 비밀
에서 이어집니다.
이번 글에서는 삼각형 Triangle()의 여러 특징들을 정리해보려 합니다.
정삼각형은 어떻게 그려질까요?
삼각형과 원의 위치 관계
Manim에서 default로 제공하는 삼각형과 원을 한번 그려봅시다.
class Triangle_Circle(Scene):
def construct(self):
SetCoordinate.construct(self)
triangle = Triangle()
circle = Circle(radius=1)
self.add(triangle, circle)
dot_cm = Dot(triangle.get_center_of_mass(), color=RED_A)
dot_c = Dot(triangle.get_center(), color=YELLOW_A)
dot_bottom = Dot(triangle.get_bottom(), color=BLUE_A)
dot_top = Dot(triangle.get_top(), color=WHITE)
self.add(dot_cm, dot_c, dot_bottom, dot_top)
np.set_printoptions(suppress= True)
print('Triangle Center of Mass : ', triangle.get_center_of_mass())
print('Triangle Center : ', triangle.get_center())
print('Triangle Bottom : ', triangle.get_bottom())
print('Triangle Top : ', triangle.get_top())
간략히 살펴보면,
dot_cm = Dot(triangle.get_center_of_mass(), color=RED_A) # 무게중심의 좌표에 Dot 생성
dot_c = Dot(triangle.get_center(), color=YELLOW_A) #도형 중심의 좌표에 Dot 생성
dot_bottom = Dot(triangle.get_bottom(), color=BLUE_A) # 도형의 제일 아래 좌표
dot_top = Dot(triangle.get_top(), color=WHITE) # 도형의 제일 위 자표
○ get_center_of_mass() : 무게중심의 좌표를 얻습니다.
○ get_center() : 도형 중심의 좌표를 얻습니다.
○ get_bottm() : 도형의 가장 밑부분 좌표를 얻습니다.
○ get_top() : 도형의 가장 윗부분 좌표를 얻습니다.
np.set_printoptions(suppress= True) # 과학적 표기방법이 아닌 표시를 한다.
print('Triangle Center of Mass : ', triangle.get_center_of_mass())
print('Triangle Center : ', triangle.get_center())
print('Triangle Bottom : ', triangle.get_bottom())
print('Triangle Top : ', triangle.get_top())
○ numpy.set_printoptions( supress = True) 는 결과 출력 시 과학적 표시(e Notation)를 조정해줍니다. suppress =True라 하면 우리가 흔히 알고 있는 소숫점으로 숫자 표기를 하고, False 일 때는 e를 사용한 Notation으로 출력합니다.
결과를 보겠습니다.
Triangle Center of Mass : [-0. -0. 0.]
Triangle Center : [-0. 0.25 0. ]
Triangle Bottom : [-0. -0.5 0. ]
Triangle Top : [-0. 1. 0.]
결과를 보면 삼각형의 무게중심이 원점이 되도록 그려지죠. 제일 위의 꼭짓점 좌표는 (0,1)입니다. 무게중심은 중선을 2:1로 나누므로 중선의 길이는 $\frac{3}{2}$ 이고, 따라서 한변의 길이가 $\sqrt{3}$입니다. 삼각형의 높이는 1-(-0.5) = 1.5이죠.
삼각형의 중심은 $(0,\textstyle{\frac14})$ 입니다(노란점.) 여기서 삼각형 제일 위까지의 거리는$\textstyle{\frac34}$ 입니다.
삼각형의 스케일 조정
도형의 크기를 결정하는 메서드 중 하나가 바로 scale()입니다. 이것이 삼각형에 어떤 영향을 주며 스케일을 조정해주는지 보겠습니다. Triangle().scale(2) 를 해보겠습니다.
class Triangle_Scale(Scene):
def construct(self):
SetCoordinate.construct(self)
triangle = Triangle().scale(2)
self.add(triangle)
dot_cm = Dot(triangle.get_center_of_mass(), color=RED_A)
dot_c = Dot(triangle.get_center(), color=YELLOW_A)
dot_bottom = Dot(triangle.get_bottom(), color=BLUE_A)
dot_top = Dot(triangle.get_top(), color=WHITE)
self.add(dot_cm, dot_c, dot_bottom, dot_top)
np.set_printoptions(suppress= True)
print('Triangle Center of Mass : ', triangle.get_center_of_mass())
print('Triangle Center : ', triangle.get_center())
print('Triangle Bottom : ', triangle.get_bottom())
print('Triangle Top : ', triangle.get_top())
나머지 부분은 위와 다 똑같고, 단위원을 제외하고 삼각형만 scale(2)를 하였습니다.
결과를 보면,
Triangle Center of Mass : [-0. -0.25 0. ]
Triangle Center : [-0. 0.25 0. ]
Triangle Bottom : [-0. -1.25 0. ]
Triangle Top : [-0. 1.75 0. ]
삼각형의 높이는 1.75-(-1.25) = 3입니다. 딱 2배가 되었죠. 그런데 몇몇 계산해 본 점들 중
Triangle Center
가 바뀌지 않는다는 것을 볼 수 있습니다. 따라서
삼각형의 스케일 업/다운은 삼각형의 중심(무게중심이 아닌)을 기준으로 한다.
라는 사실을 알 수 있습니다.
이를 알 수 있는 또 좋은 방법이 있습니다. 바로 SurroundingRectangle()을 이용해서 판단해 보는 것입니다.
삼각형과 SurroundingRectangle()
Manim에서 제공하는 임의의 mobject에 대해서 SurroundingRectangle()은
class SurroundingRectangle(mobject, color='#FFFF00', buff=0.1, corner_radius=0.0, **kwargs)
로 생성합니다. 간단히 생각해서 mobject를 감싸는 reactangle이라는 의미이고, color와 buff 등을 지정할 수 있죠.
특히
○ buff =0으로 정하면 mobject를 딱 감싸는(상하좌우 간격 여유 없이) 직사각형을 제공합니다.
class Triangle_Scale2(Scene):
def construct(self):
SetCoordinate.construct(self)
triangle0 = Triangle(color=WHITE)
surrRec0 = SurroundingRectangle(triangle0, buff=0, color=WHITE)
self.add(triangle0, surrRec0)
triangle1= triangle0.copy().scale(2)
triangle1.set_color(YELLOW)
surrRec1 = surrRec0.copy().scale(2)
surrRec1.set_color(YELLOW)
self.add(triangle1, surrRec1)
triangle2 = triangle0.copy().scale(4)
triangle2.set_color(BLUE_A)
surrRec2 = surrRec0.copy().scale(4)
surrRec2.set_color(BLUE_A)
self.add(triangle2, surrRec2)
np.set_printoptions(suppress= True)
print('SurroundRectangle0 : ', surrRec0.get_center())
print('SurroundRectangle1 : ', surrRec1.get_center())
print('SurroundRectangle2 : ', surrRec2.get_center())
위 코드를 보면 기본 삼각형과 각각 scale을 2배, 4배 한 삼각형과, 그 각각을 둘러싼 SurroundingRectangle 같이 표시해보고, 또 이런 Rectangle들의 중심 좌표를 출력해봅니다.
결과를 보실까요?
SurroundRectangle0 : [-0. 0.25 0. ]
SurroundRectangle1 : [-0. 0.25 0. ]
SurroundRectangle2 : [0. 0.25 0. ]
SurroundingRectangle의 중심은 변화 없이 유지되죠. 삼각형은 각각의 rectangle안에 딱 접하고 있습니다.
따라서 scale 조정은 surrounding rectangle의 중심을 기준으로 scale up/down이 됨을 알 수 있습니다.
삼각형의 회전
2022.09.21 - [파이썬/MANIM] - Manim. 삼각형 그리기
에서 도형의 회전은 about_point 라는 조건이 있으면 대상 점을 중심으로 회전한다는 것을 알아봤습니다. 만일 이 조건을 생략하면,
Manim은 디폴트로 어떠한 조건으로 회전을 명령할까요?
결론부터 얘기하면 삼각형을 감싸는 Surrounding Rectangle의 중심을 기준으로 회전합니다.
class Triangle_Rotate(Scene):
def construct(self):
SetCoordinate.construct(self)
deg = 90
tri0 = Triangle(color=WHITE).scale(2)
surr0 = SurroundingRectangle(tri0, color=WHITE, buff=0)
txt0 = Text('Before Rotation', color=WHITE, font_size=30).move_to([-2, 2, 0])
self.add(tri0, surr0,txt0)
tri = tri0.copy().rotate(deg * DEGREES)
tri.set_color(YELLOW)
surr = surr0.copy().rotate(deg * DEGREES).set_color(YELLOW)
txt = Text('After Rotation', color=YELLOW, font_size=30).move_to([2, -2, 0])
self.add(tri, surr, txt)
기본 삼각형의 scale 2배짜리 삼각형과 그를 감싼 직사각형, 그리고 이 둘을 90도로 회전한 결과를 그림으로 나타내 보는 것입니다.
하얀 삼각형과 노란 삼각형을 비교해봐도, 무게중심을 기준으로 회전하진 않아 보이죠? 답은 SurroundingRectangle의 중심을 기준으로의 회전이었습니다.
이제 scale이나 rotate 시 디폴트 옵션이 무엇인지 알았으니 사용할 때 헷갈림이 없을 것 같네요.
'파이썬 > MANIM' 카테고리의 다른 글
Manim. 그래프 그리기 (0) | 2022.09.27 |
---|---|
Manim. 도형 회전 rotate의 비밀 (0) | 2022.09.22 |
Manim. 삼각형 그리기 (0) | 2022.09.21 |
Manim. 정사각형 그리기 (0) | 2022.09.16 |
Manim. 원 그리기 (0) | 2022.09.14 |
댓글