본문 바로가기
스터디/OpenGL

[ OpenGL ] 질량-용수철 시스템

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

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

 

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

namespace jm
{
	class Example : public Game2D
	{
	public:
		RigidCircle rb0, rb1;

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

		void reset()
		{
			// Initial position and velocity
			rb0.pos = vec2(0.0f, 0.5f);
			rb0.vel = vec2(0.0f, 0.0f);
			rb0.color = Colors::hotpink;
			rb0.radius = 0.03f;
			rb0.mass = 1.0f;

			rb1.pos = vec2(0.5f, 0.5f);
			rb1.vel = vec2(0.0f, 0.0f);
			rb1.color = Colors::yellow;
			rb1.radius = 0.03f;
			rb1.mass = rb0.mass * std::pow(rb1.radius / rb0.radius, 2.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
		{
			const float dt = getTimeStep() * 0.4f;
			const float epsilon = 0.5f;

			// physics update (Temporarily disabled)
			//rb0.update(dt);
			//rb1.update(dt);

			// coefficients
			const vec2 gravity(0.0f, -9.8f);
			const float l0 = 0.5f;
			const float coeff_k = 50.0f; // 용수철 계수
			const float coeff_d = 10.0f;

			// update rb1 (Note: rb0 is fixed)
			{
				const auto distance = (rb1.pos - rb0.pos).getMagnitude();
				const auto direction = (rb1.pos - rb0.pos) / distance; // unit vector

				// compute stiffness force
				const auto spring_force = direction * -(distance - l0) * coeff_k +
					direction * -(rb0.vel).getDotProduct(direction) * coeff_d;

				// compute damping force

				const auto accel = gravity + spring_force / rb1.mass;

				rb1.vel += accel * dt;
				rb1.pos += rb1.vel * dt;
			}

			// draw
			drawWall();

			// spring
			drawLine(Colors::red, rb0.pos, Colors::red, rb1.pos);

			// mass points
			rb0.draw();
			rb1.draw();

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

	};
}

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

	return 0;
}

 

 

용수철.mp4
1.18MB

 

**** 키워드 : mass_ spring model, Hooke's Law - 용수철의 힘을 계산하는 법칙, Damping Force, Total Spring Forces, 회전 속도, 각 가속도, 동역학, 선형 속도(회전을 포함하지 않는 속도), 2차원에서의 회전은 1자유도, 3차원에서는 3자유도 ****