본문 바로가기
스터디/OpenGL

[ OpenGL ] 공 튀기기 시뮬레이션

by 알 수 없는 사용자 2019. 10. 31.

( ** 인프런에서 들은 강의 '홍정모의 게임 만들기 연습 문제 패키지'를 통해서 공부한 내용과 연습 문제 풀이입니다. **)

 

#include "Game2D.h"
#include "Examples/PrimitivesGallery.h"
#include "RandomNumberGenerator.h"
#include <vector>
#include <memory>

namespace jm
{
	class RigidCircle
	{
	public:
		vec2 pos;
		vec2 vel;
		float radius = 0.1f;

		void draw()
		{
			beginTransformation();
			{
				translate(pos);
				drawFilledCircle(Colors::hotpink, radius - 1e-3f);
				setLineWidth(2.0f);
				drawWiredCircle(Colors::black, radius);
			}
			endTransformation();
		}

		void update(const float & dt)
		{
			static const vec2 gravity = vec2(0.0f, -9.8f); // 중력가속도
			static const float coef_res = 0.3f; // 완전 탄성 법칙 coefficient of restitution
			static const float coef_friction = 0.99f; // friction (not phtsical) 마찰 계수
			// 정지 마찰력 운동 마찰력


			// numerical integration
			vel += gravity * dt;
			pos += vel * dt; 

			// wall collision, friction
			if (1.0f - pos.x <= radius) // right wall
			{
				pos.x = 1.0f - radius;

				if (vel.x >= 0.0f) // 복잡한 시뮬레이션을 구현할 때 안전장치
					vel.x *= -1.0f * coef_res;
			}

			if (pos.x + 1.0f <= radius) // left wall
			{
				pos.x = -1.0f + radius;

				if (vel.x <= 0.0f) // 복잡한 시뮬레이션을 구현할 때 안전장치
					vel.x *= -1.0f * coef_res;
			}

			if (pos.y <= -1.0f + radius) // ground
			{
				pos.y = -1.0f + radius;

				if (vel.y <= 0.0f) // 복잡한 시뮬레이션을 구현할 때 안전장치
					vel.y *= -1.0f * coef_res;
				
				vel.x *= coef_friction;
			}
		}
	};

	class Example : public Game2D
	{
	public:
		RigidCircle rigid_body;

		Example()
			: Game2D()
		{
			reset();
		}

		void reset()
		{
			// Initial position and velocity
			rigid_body.pos = vec2(-0.8f, 0.3f);
			rigid_body.vel = vec2(10.0f, 0.0f);
		}

		void drawWall()
		{
			setLineWidth(5.0f);
			drawLine(Colors::blue, { -1.0f, -1.0f }, Colors::blue, { 1.0f, -1.0f });
			drawLine(Colors::blue, { 1.0f, -1.0f }, Colors::blue, { 1.0f, 1.0f });
			drawLine(Colors::blue, { -1.0f, -1.0f }, Colors::blue, { -1.0f, 1.0f });
		}

		void update() override
		{
			// physics update
			rigid_body.update(getTimeStep() * 0.1f);

			// draw
			drawWall();
			rigid_body.draw();

			// reset button
			if (isKeyPressedAndReleased(GLFW_KEY_R)) reset();
		}
	};
}

int main(void)
{
	jm::Example().run();

	return 0;
}

 

공튀기기.mp4
0.78MB

 

**** 키워드 : 뉴턴의 제 2법칙, 미분 방정식, 유한차분법, 완전 탄성 충돌, 반발 계수, 마찰 계수, 정지 마찰력, 운동 마찰력 ****