본문 바로가기

카테고리 없음

삼각함수로 하트 그리기

https://github.com/moonimax/GameMath_CMaker/tree/trigonometric-functions-with-Heart

 

GitHub - moonimax/GameMath_CMaker: CMaker를 활용한 게임 수학 구현

CMaker를 활용한 게임 수학 구현. Contribute to moonimax/GameMath_CMaker development by creating an account on GitHub.

github.com

 

 

여기에서 약간의 하트 알파값과 애니메이션을 넣게 된다면.. 다음과 같이 할 수 있다.

 

 

 

// 게임 로직을 담당하는 함수
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 scaleSpeed = 20.f;	// 입력에 따른 크기 변화 속도를 지정하는 변수
	static float duration = 1.5f;
	static float elapsedTime = 0.f;

	elapsedTime += InDeltaSeconds;
	elapsedTime = Math::FMod(elapsedTime, duration);
	float currentRad = (elapsedTime / duration) * Math::TwoPI;
	float alpha = (sinf(currentRad) + 1) * 0.5f;	// alpha 값은 선형보간에 의해 [0,1] 을 왕복하게 된다.

	// X축과 Y축 입력을 결합해 입력 벡터를 생성한다.
	// X, Y축을 동시에 입력받게 되면 벡터 크기 값이 급성장함으로 정규화시킨다. GetNormalize()
	Vector2 inputVector = Vector2(input.GetAxis(InputAxis::XAxis), input.GetAxis(InputAxis::YAxis)).GetNormalize();
	Vector2 deltaPosition = inputVector * moveSpeed * InDeltaSeconds;
	float deltaScale = input.GetAxis(InputAxis::ZAxis) * scaleSpeed * InDeltaSeconds;	// Z축 입력에 따른 크기의 변화량을 계산한다.

	//물체의 최종 상태 설정
	currentPosition += deltaPosition;
	currentScale = Math::Lerp(scaleMin, scaleMax, alpha);	

}

// 렌더링 로직을 담당하는 함수
void SoftRenderer::Render2D()
{
	// 렌더링 로직에서 사용하는 모듈 내 주요 레퍼런스
	auto& r = GetRenderer();	// 화면의 시각적 표현을 위해 렌더러 모듈의 래퍼런스를 가져옴
	const auto& g = Get2DGameEngine();

	// 배경에 격자 그리기
	DrawGizmo2D();

	// 렌더링 로직의 로컬 변수
	float rad = 0.f;
	static float increment = 0.001f;
	static std::vector<Vector2> hearts;
	HSVColor hsv(0.f, 1.f, 0.85f);
	// 하트 구성하는 점 생성
	if(hearts.empty())
	{
	
		for (rad = 0.f; rad < Math::TwoPI; rad += increment)
		{
			float sin = sinf(rad);
			float cos = cosf(rad);
			float cos2 = cosf(2 * rad);
			float cos3 = cosf(3 * rad);
			float cos4 = cosf(4 * rad);
			float x = 16.f * sin * sin * sin;
			float y = 10 * cos - 5 * cos2 - 2 * cos3 - cos4;
			hearts.push_back(Vector2(x, y));

		}

	}

	// 각 값을 초기화 후 색상을 증가시키면서 점에 대응
	rad = 0.f;

	for (auto const& v : hearts)
	{
		// 소프트 웨어가 제공하는 HSV 모델의 H는 라디안 값이 아닌 [0.1] 범위 값을 사용한다. 따라서 원의 라디언 값에 해당하는 범위로 변경한다.
		hsv.H = rad / Math::TwoPI;
		r.DrawPoint(v * currentScale + currentPosition, hsv.ToLinearColor());
		rad += increment;
	}

}

 

 

하트 회전시키기

 

// 게임 로직과 렌더링 로직이 공유하는 변수
// 변수 선언 영역
Vector2 currentPosition(100.f, 100.f);
float currentScale = 10.f;
float currentDegree = 0.1f;

// 게임 로직을 담당하는 함수
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 scaleSpeed = 20.f;	// 입력에 따른 크기 변화 속도를 지정하는 변수
	static float rotateSpeed = 180.f;


	// X축과 Y축 입력을 결합해 입력 벡터를 생성한다.
	// X, Y축을 동시에 입력받게 되면 벡터 크기 값이 급성장함으로 정규화시킨다. GetNormalize()
	Vector2 inputVector = Vector2(input.GetAxis(InputAxis::XAxis), input.GetAxis(InputAxis::YAxis)).GetNormalize();
	Vector2 deltaPosition = inputVector * moveSpeed * InDeltaSeconds;
	float deltaScale = input.GetAxis(InputAxis::ZAxis) * scaleSpeed * InDeltaSeconds;	// Z축 입력에 따른 크기의 변화량을 계산한다.
	float deltaDegree = input.GetAxis(InputAxis::WAxis) * rotateSpeed * InDeltaSeconds;


	//물체의 최종 상태 설정
	currentPosition += deltaPosition;
	currentDegree += deltaDegree;

}

// 렌더링 로직을 담당하는 함수
void SoftRenderer::Render2D()
{
	// 렌더링 로직에서 사용하는 모듈 내 주요 레퍼런스
	auto& r = GetRenderer();	// 화면의 시각적 표현을 위해 렌더러 모듈의 래퍼런스를 가져옴
	const auto& g = Get2DGameEngine();

	// 배경에 격자 그리기
	DrawGizmo2D();

	// 렌더링 로직의 로컬 변수
	float rad = 0.f;
	static float increment = 0.001f;
	static std::vector<Vector2> hearts;
	HSVColor hsv(0.f, 1.f, 0.85f);
	// 하트 구성하는 점 생성
	if(hearts.empty())
	{
	
		for (rad = 0.f; rad < Math::TwoPI; rad += increment)
		{
			float sin = sinf(rad);
			float cos = cosf(rad);
			float cos2 = cosf(2 * rad);
			float cos3 = cosf(3 * rad);
			float cos4 = cosf(4 * rad);
			float x = 16.f * sin * sin * sin;
			float y = 10 * cos - 5 * cos2 - 2 * cos3 - cos4;
			hearts.push_back(Vector2(x, y));

		}

	}

	float sin = 0.f; float cos = 0.f;
	// currentDegree sin, cos 얻어낸다. 
	Math::GetSinCos(sin, cos, currentDegree);
	// 각 값을 초기화 후 색상을 증가시키면서 점에 대응
	rad = 0.f;

	for (auto const& v : hearts)
	{
		// 소프트 웨어가 제공하는 HSV 모델의 H는 라디안 값이 아닌 [0.1] 범위 값을 사용한다. 따라서 원의 라디언 값에 해당하는 범위로 변경한다.
		// 1. 점에 크기를 적용한다
		Vector2 scaledV = v * currentScale;
		// 2. 크기가 변한 점을 회전시킴
		Vector2 rotatedV = Vector2(scaledV.X * cos - scaledV.Y * sin, scaledV.X * sin + scaledV.Y * cos);
		// 3. 회전 시킨 점 이동
		Vector2 transltedV = rotatedV + currentPosition;
		hsv.H / rad / Math::TwoPI;
		r.DrawPoint(transltedV, hsv.ToLinearColor());

	}

}