If you're seeing this message, it means we're having trouble loading external resources on our website.

웹 필터가 올바르게 작동하지 않으면 도메인 *. kastatic.org*.kasandbox.org이 차단되어 있는지 확인하세요.

주요 내용

중력 및 마찰력 모델링

이제는 여태까지 구현한 힘을 좀 더 현실감 있게 만들기 위해 지난 예제에서 만든 중력을 개선하면서 여기에 마찰력을 추가시켜 봅시다.

지구의 중력

지난번 예제에서 아주 부정확한 사실을 발견할 수 있습니다. 작은 원일 수록 더욱 빠르게 떨어집니다. 뉴턴의 제2법칙에 따라 질량이 작으면 가속도가 크다고 설정했기 때문입니다.
하지만 실제로는 그렇지 않습니다. 피사의 사탑에 올라가서 질량이 다른 공 두 개를 동시에 떨어뜨리면 어떤 것이 땅에 먼저 닿을까요? 1589년 갈릴레오가 정확히 이것을 실험해본 결과 둘은 같은 가속도를 가지고 떨어져 땅에 동시에 닿았습니다.
왜 그럴까요? 이 단원에서 더 알아보겠지만, 중력은 물체의 질량에 다라 달라집니다. 물체가 무거울수록 힘이 더 크기 때문에 힘이 질량에 따른다면, 힘을 질량으로 나누었을 때 질량은 사라집니다. 프로그램에 만들었던 질량에 따른 가속도(중력)에 이를 구현하면 다음과 같습니다:
for (var i = 0; i < movers.length; i++) {
    gravity.set(0, 0.1 * movers[i].mass);
    movers[i].applyForce(gravity);
    …
}
이제 물체들이 같은 속도로 떨어지지만, 바람의 강도는 질량과 독립적으로 작용하기 때문에 작은 물체들이 여전히 훨씬 더 빠르게 오른쪽으로 가속합니다.
힘을 만들어내는 것은 사실 매우 강력한 툴입니다. ProcessingJS는 여러분이 주인인 픽셀 세계입니다. 따라서 어떤 힘을 구현해 놓으면, 적어도 그 환경에서는 이 힘이 곧 법입니다. 그럼에도 불구하고 간혹 이 전부를 실제처럼 구현하기 막막할 상황이 올 수도 있습니다.
이럴 때는 수많은 고등학교 물리 교과서를 열어보면 전부 중력, 자기력, 마찰력, 장력, 탄성 등 수많은 종류의 힘에 대한 그림 설명과 공식을 찾아볼 수 있을 겁니다. 아니면 칸아카데미 물리 과목에서 찾아보세요. 지금부터는 수많은 힘 중에서 마찰력과 중력 두 가지 힘을 배워 봅시다. 이 단원에서 배울 마찰력과 중력은 앞으로 만들 모든 ProcessingJS 프로그램에 항상 구현시켜 놓아야 할 만큼 근본적이고 중요한 것은 아닙니다. 하지만 이 두 가지 힘을 배우면서 다음과 같은 목적을 달성할 수 있습니다:
  • 힘에 대한 개념을 이해합니다.
  • 힘에 대한 공식을 두 부분으로 나눠서 이해합니다:
    • 힘의 방향을 어떻게 계산할까요?
    • 힘의 크기를 어떻게 계산할까요?
  • 이 공식을 ProcessingJS 코드에 적용하여 MoverapplyForce() 함수에 쓸 PVector를 만듭니다.
두 힘을 이해하는데 위 단계를 따른다면 어느 날, 새벽 세시에 구글에서 "원자핵의 약력" 같은 생소한 종류의 힘을 찾아보더라도 이를 ProcessingJS 프로그램에 녹여 구현할 수 있게 될 정도의 실력을 갖출 수 있습니다.
공식 다루기
잠시 후면 마찰력 공식을 보게 될 것입니다. 물리 공식은 이전에 배운 적이 있습니다. 이 페이지를 보고 있다면 바로 전에 뉴턴 제2법칙, F, with, vector, on top, equals, M, times, A, with, vector, on top​ (힘 = 질량 * 가속도) 을 배웠을 겁니다. 이 공식은 매우 단순하기 때문에 배울 때 그리 오래 걸리지는 않았습니다. 하지만 세상살이가 항상 쉬운건 아니죠. 과정 맨 처음에 잠깐 배웠던 정규분포식을 봅시다.
f, left parenthesis, x, comma, mu, comma, sigma, right parenthesis, equals, start fraction, 1, divided by, sigma, square root of, 2, pi, end square root, end fraction, e, start superscript, left parenthesis, minus, start fraction, left parenthesis, x, minus, mu, right parenthesis, squared, divided by, 2, sigma, squared, end fraction, right parenthesis, end superscript
보시다시피 공식에 그리스 문자가 매우 많습니다. 그럼 이제 마찰력 공식을 살펴봅시다.
마, 찰, 력, with, vector, on top, equals, minus, µ, N, v, with, hat, on top
수학이나 물리를 배운지 오래되서 공식을 안본지 한참 지났다면 다음으로 넘어가기전에 세 가지 중요한 점을 알아두어야 합니다.
  • 왼편에 제목을 쓰고 오른편에서 구현한다. 코딩과 똑같은 부분입니다! 코딩에서 왼편은 구현할 명령어의 이름을 정의하고 오른편은 그 명령어를 실제로 구현하는 역할을 합니다. 위에 나와 있는 마찰력 공식의 경우, 왼쪽은 계산하고자 하는 값을 나타내고 오른쪽은 실제로 계산을 어떻게 해야 하는지를 나타냅니다.
  • 수치가 벡터인가 스칼라인가? 알고있어야 할 매우 중요한 점 중 또 하나는 때때로 어떤 수치가 벡터인지 스칼라인지 정확히 알아야 합니다. 예를 들면 마찰력의 경우 벡터가 쓰입니다. 위 공식에서 "마찰력" 위에 표시한 화살표는 이 값이 벡터라는 것을 나타냅니다. 벡터는 크기와 방향을 가지고 있습니다. 식의 우변또한 마찬가지로 벡터를 가지고 있습니다 (v, with, hat, on top: 속도의 단위벡터).
  • 기호 여러 개가 나란히 붙어있을 때는 서로 곱해준다. 위 공식은 사실 다음과 같은 네 가지 부분으로 나뉘어져 있습니다: -1, µ, N, v, with, hat, on top. 마찰력 공식은 네 요소를 서로 곱해서 하나의 공식으로 나타낸 것입니다: F, r, i, c, t, i, o, n, with, vector, on top, equals, minus, µ, N, v, with, hat, on top

마찰력

마찰력에 대해 알아보고 여러 단계에 걸쳐 배워 봅시다.
마찰력은 산일적인 힘입니다. 산일적인 힘이란 어떤 물체가 운동할 때 총 에너지가 점점 줄어드는 힘을 일컫는 것입니다. 차를 운전하고 있다고 가정합시다. 브레이크 페달을 밟으면 자동차의 브레이크는 마찰력을 이용해 바퀴의 운동을 방해하여 속도를 낮춥니다. 이때, 운동에너지는 열에너지로 바뀝니다. 두 면이 서로 맞닿으면 그 즉시 마찰력이 발생합니다. 마찰력에는 정지마찰력 (정지 중인 물체와 면)과 운동마찰력 (이동 중인 물체와 면) 두 종류가 있으나 프로그래밍 목적에 맞는 운동마찰력만 배워 봅시다.
다음 그림으로 마찰력 공식을 더 쉽게 이해해 봅시다.
마찰력 = −1µN*v 공식과 함께 썰매 타는 사람
이제 이 공식을 마찰력의 두 성분 (방향과 크기)으로 나누어 알아봅시다. 위 그림을 보면 마찰력은 속도와 방향이 반대입니다. 공식에서 나와있는 minus, 1, times, v, with, hat, on top 부분, 즉 -1 곱하기 속도의 단위 벡터는 마찰력이 속도와 방향이 반대라는 것을 말해줍니다. ProcessingJS에서 이것은 속도 벡터를 정규화 시킨 다음 -1로 곱해주는 것을 의미합니다.
var friction = velocity.get();
friction.normalize();
// 마찰력의 방향을 알아봅시다 
// (속도와 반대 방향의 단위 벡터)
friction.mult(-1);
여기서 두 개의 단계를 추가해 봅시다. 첫 번째, 실수로 속도 벡터의 방향을 뒤집어 놓는 것을 방지하기 위해 벡터를 복사합니다. 두 번째, 벡터를 정규화합니다. 정규화를 하는 이유는 마찰력의 크기는 이동속도와 관계가 없고 크기를 1로 시작하면 나중에 크기를 바꿔줄 때 더욱 편리하기 때문입니다.
공식에서 마찰력의 크기는 mu, times, N 으로 정의됩니다. 앞에 있는 그리스 문자 뮤는 마찰계수 를 나타냅니다. 마찰계수는 어떤 면 고유의 마찰력으로 그 종류에 따라 수치가 다른 값입니다. 값이 클수록 마찰력이 더 강해지고 값이 작을수록 마찰력은 더 약해집니다. 예를 들어 얼음은 사포보다 훨씬 더 낮은 마찰계수를 가지고 있습니다. ProcessingJS 의 세계에서는 마찰계수를 원하는 정도로 설정할 수 있습니다.
var c = 0.01;
그다음 부분 N수직항력을 나타냅니다. 물체가 서로에 닿을 때 발생하는 접촉력입니다. 좀 더 정확히 N은 접촉력의 수직 요소라고 할 수 있습니다.
도로를 달리는 자동차를 상상해 봅시다. 자동차는 도로를 밀고 있고 뉴턴의 제3법칙에 따르면 도로도 자동차를 밀고 있습니다. 이것이 수직항력입니다. 물체가 수평으로 움직일 때 수직항력은 질량에 중력을 곱한 값으로 F, start subscript, n, end subscript, equals, m, g라고 씁니다. 이 말은 가벼운 스포츠카는 상대적으로 작은 수직항력을 가하고, 따라서 큰 트레일러보다 작은 마찰력을 경험한다는 뜻입니다.
그러나 위 그림에서 물체는 일정 각도로 표면을 따라 움직이고 있고, 그러면 수직 항력을 계산하는 것이 약간 더 복잡합니다. 중력과 방향이 동일하지 않기 때문입니다. 이 때문에 각도와 삼각법에 대해 알아야 합니다.
지금은 ProcessingJS 프로그램에서 적당히 괜찮은 시뮬레이션을 구현하는 것이지 완벽한 시뮬레이션이 목적이 아닙니다. 예를 들어 수직항력의 크기가 항상 1.이라고 가정한다면 N을 다음과 같이 간단히 할 수 있습니다:
var normal = 1;
다음 단원에서 삼각법을 살펴볼 때 놓친 세부사항을 다시 고려해 마찰력 예제를 좀 더 정교하게 만들어 보도록 하겠습니다.
이제 마찰력의 크기와 방향을 모두 알아냈으므로 이제 둘을 합쳐봅시다.
var c = 0.01;
var normal = 1;
var frictionMag = c * normal;
var friction = movers[i].velocity.get();
friction.mult(-1);
friction.normalize();
friction.mult(frictionMag);
그다음, 이전에 만든 힘 예제에 마찰력을 추가하여 여러 객체가 동시에 바람, 중력, 마찰력에 영향을 받도록 만들어봅시다.
이 프로그램을 계속 관찰하다 보면 원들이 서서히 느려지면서 어느 순간 모두 제자리에 멈춰있는 것을 볼 수 있습니다. 마찰력은 원들이 움직이는 반대 방향으로 힘을 가해서 속도를 서서히 늦추는 역할을 합니다. 이는 여러분이 구현하고 싶어 하는 것에 따라 도움이 될 수도 장애물이 될 수도 있습니다.

본 "내추럴 시뮬레이션" 과정은 다니엘 쉬프만(Daniel Shiffman)이 저술한 "The Nature of Code"의 내용을 차용한 것이며, 본 내용물의 저작권은 Creative Commons Attribution-NonCommercial 3.0 Unported License를 적용합니다.