반응형
움직이는 사인 곡선을 만들어보자. 마치 파형이 이동하는 듯한.
기본 구상
$\sin ( \theta + \alpha )$는 $\sin \theta$인 곡선이 $\alpha$만큼 왼쪽으로 쉬프트 된 곡선이다.
위 그림은 $\sin \theta$를 $\frac {\pi} {4}$ 만큼씩 왼쪽으로 이동한 것으로, 시간 단위별로 이렇게 이동시키면, 마치 사인파가 왼쪽으로 흐르는 듯한 효과를 낼 수 있을 것이다.
코딩
축 그리기
x축과 y축을 그린다.
def draw_axis(self):
x_axis = Line(np.array([-4,0,0]), np.array([4,0,0]))
y_axis = Line(np.array([-4,2,0]), np.array([-4,-2,0]))
self.add(x_axis, y_axis)
self.x_min = -4
self.x_max = 4
나중에 사인 그래프를 그릴 때, x축 최솟값과 최댓값을 사용하기 위해 self.x_min=-4, self.x_max=4로 해서 전역 변수로 저장해 둔다.
사인 웨이브 그리기
기본 전략은 다음과 같다.
- $\sin x$에 대한 그래프를 그린다.
- 프레임이 변할 때 마다 dx 값이 커지게 하고, $\sin (x+dx)$ 그래프로 업데이트되게 한다.
$\sin x$에 대한 그래프는, 계속해서 만들어져야 하기에 그래프를 얻어내는 것을 함수로 만들어두자.
def get_sine_wave(self, dx=0):
return FunctionGraph(
# sin(0)부터 시작하게 하기 위함임. x_min=-4이기에 4를 더해줘서 0을 만듦
lambda x: np.sin((x-self.x_min + dx)),
x_min=self.x_min, x_max=self.x_max
)
먼저 최초 사인 그래프를 생성해서 화면에 표출한다.
sine_wave = self.get_sine_wave()
self.add(sine_wave)
이제 dx를 조금씩 커지게 하면서 sine_wave를 업데이트 하면 된다.
dx를 조금씩 커지게 하는 것은 ValueTracker를 이용하자.
초기값은 0으로 하고, 4초 동안에 0 ~ $2 \pi$까지 서서히 증가하게 한다.
vt = ValueTracker(0)
moving_time = 4
moving_length = 2*PI
self.play(vt.set_value, moving_length, run_time=moving_time, rate_func=linear)
sine_wave가 영상 프레임마다 변하게 하는 것은, add_updater(update_wave)와 같이해서 프레임마다 update_wave 함수가 호출되도록 하고, 이 함수 내에서 새로운 그래프를 얻어내고, 그 그래프로 sine_wave가 업데이트되도록 한다.
def update_wave(wave):
wave.become(self.get_sine_wave(dx=vt.get_value()))
sine_wave.add_updater(update_wave)
전체 소스는 다음과 같다.
from manimlib.imports import *
class MovingWave(Scene):
def construct(self):
self.draw_axis()
self.draw_sine_wave()
def draw_axis(self):
x_axis = Line(np.array([-4,0,0]), np.array([4,0,0]))
y_axis = Line(np.array([-4,2,0]), np.array([-4,-2,0]))
self.add(x_axis, y_axis)
self.x_min = -4
self.x_max = 4
def draw_sine_wave(self):
sine_wave = self.get_sine_wave()
vt = ValueTracker(0)
def update_wave(wave):
wave.become(self.get_sine_wave(dx=vt.get_value()))
sine_wave.add_updater(update_wave)
self.add(sine_wave)
self.wait(2)
# 사인파가 4초에 2PI 만큼 이동하게
moving_time = 4
moving_length = 2*PI
self.play(vt.set_value, moving_length, run_time=moving_time, rate_func=linear)
self.wait()
def get_sine_wave(self, dx=0):
return FunctionGraph(
# sin(0)부터 시작하게 하기 위함임. x_min=-4이기에 4를 더해줘서 0을 만듦
lambda x: np.sin((x-self.x_min + dx)),
x_min=self.x_min, x_max=self.x_max
)
만들어진 동영상
-끝-
반응형
'Programming > Manim Project' 카테고리의 다른 글
사인 파의 진폭을 변형시키면서 사인파 이동시키기 (0) | 2020.09.17 |
---|---|
계속해서 흘러가는 사인 파형 만들기 (0) | 2020.09.17 |
원 위의 점이 돌면서 사인/코사인 곡선 그리기 (0) | 2020.09.15 |
원 위의 점이 이동하면서 사인 곡선 그리기 (1) | 2020.09.14 |
python의 for 루프 설명하기 (0) | 2020.05.31 |