수학/이득우의 게임 수학 - 실습 예제

sin 함수를 사용한 하트의 박동 표현

monstro 2025. 8. 27. 10:47
728x90
반응형

- 개요

출처 : https://ko.wikipedia.org/wiki/%EC%82%BC%EA%B0%81_%ED%95%A8%EC%88%98

 

삼각 함수 중에서 sin 함수각의 변화에 따라 주기적으로 -1과 1의 값을 왕복한다

이런 성질을 사용하여 시간에 따라 부드럽게 반복되는 애니메이션을 만들 수 있다

 

- 예제

// // 매 프레임마다 호출하는 함수
void SoftRenderer::Update2D(float InDeltaSeconds)
{
	// 사용자로부터 입력을 받기 위한 레퍼런스
	auto& g = Get2DGameEngine();
	const InputManager& input = g.GetInputManager();

	// 로컬 변수
	// 하트의 이동 속도 / 하트의 최소 크기 / 하트의 최대 크기 / 애니메이션의 왕복 시간 / 현재 경과한 시간
	static float moveSpeed = 100.f;
	static float scaleMin = 5.f;
	static float scaleMax = 20.f;
	static float duration = 1.5f;
	static float elapsedTime = 0.f;
	
	// 매핑된 키로부터 사용자가 입력한 값을 가져오고, 입력값 * 속도 * 프레임시간의 값으로 2차원 벡터를 생성
	Vector2 inputVector = Vector2(input.GetAxis(InputAxis::XAxis), input.GetAxis(InputAxis::YAxis)).GetNormalize();
	Vector2 deltaPosition = inputVector * moveSpeed * InDeltaSeconds;

	// 로직의 구성 - 시간에 따른 각도를 인자로 하여 sin 함수의 값 반환
	// 1) 현재 경과 시간에 프레임당 경과 시간을 더함
	// 2) 나머지 연산을 사용하여 현재 경과 시간이 애니메이션의 왕복 시간을 넘으면 0으로 설정
	// 3) (현재 경과 시간 / 애니메이션의 왕복 시간) * 2π의 식으로 현재 시간에 대응하는 각 반환
	// 4) 바로 아래의 선형 보간을 위애 [-1, 1]의 값이 아닌 1을 더하고 0.5를 곱하여 [0, 1]의 값 반환
	elapsedTime += InDeltaSeconds;
	elapsedTime = Math::FMod(elapsedTime, duration);
	float currentRad = (elapsedTime / duration) * Math::TwoPI;
	float alpha = (sinf(currentRad) + 1) * 0.5f;

	// 하트의 최종 위치 벡터와 최종 크기 설정, 크기의 경우 선형 보간 사용 
	// 선형 보간 : scaleMin + alpha * (scaleMax - scaleMin)
	currentPosition += deltaPosition;
	currentScale = Math::Lerp(scaleMin, scaleMax, alpha);
}

 

sin 함수를 사용하여 부드럽게 반복하는 애니메이션을 만들 수 있다

이때 예제에서는 [-1, 1]의 값이 아닌, 선형 보간을 위해 [0, 1]의 값을 사용하도록 구성하였다

 

- 최종 실행 결과

728x90
반응형