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=M×A​ (힘 = 질량 * 가속도) 을 배웠을 겁니다. 이 공식은 매우 단순하기 때문에 배울 때 그리 오래 걸리지는 않았습니다. 하지만 세상살이가 항상 쉬운건 아니죠. 과정 맨 처음에 잠깐 배웠던 정규분포식을 봅시다.
f(x,μ,σ)=1σ2πe((xμ)22σ2)
보시다시피 공식에 그리스 문자가 매우 많습니다. 그럼 이제 마찰력 공식을 살펴봅시다.
=µNv^
수학이나 물리를 배운지 오래되서 공식을 안본지 한참 지났다면 다음으로 넘어가기전에 세 가지 중요한 점을 알아두어야 합니다.
  • 왼편에 제목을 쓰고 오른편에서 구현한다. 코딩과 똑같은 부분입니다! 코딩에서 왼편은 구현할 명령어의 이름을 정의하고 오른편은 그 명령어를 실제로 구현하는 역할을 합니다. 위에 나와 있는 마찰력 공식의 경우, 왼쪽은 계산하고자 하는 값을 나타내고 오른쪽은 실제로 계산을 어떻게 해야 하는지를 나타냅니다.
  • 수치가 벡터인가 스칼라인가? 알고있어야 할 매우 중요한 점 중 또 하나는 때때로 어떤 수치가 벡터인지 스칼라인지 정확히 알아야 합니다. 예를 들면 마찰력의 경우 벡터가 쓰입니다. 위 공식에서 "마찰력" 위에 표시한 화살표는 이 값이 벡터라는 것을 나타냅니다. 벡터는 크기와 방향을 가지고 있습니다. 식의 우변또한 마찬가지로 벡터를 가지고 있습니다 (v^: 속도의 단위벡터).
  • 기호 여러 개가 나란히 붙어있을 때는 서로 곱해준다. 위 공식은 사실 다음과 같은 네 가지 부분으로 나뉘어져 있습니다: -1, µ, N, v^. 마찰력 공식은 네 요소를 서로 곱해서 하나의 공식으로 나타낸 것입니다: Friction=µNv^

마찰력

마찰력에 대해 알아보고 여러 단계에 걸쳐 배워 봅시다.
마찰력은 산일적인 힘입니다. 산일적인 힘이란 어떤 물체가 운동할 때 총 에너지가 점점 줄어드는 힘을 일컫는 것입니다. 차를 운전하고 있다고 가정합시다. 브레이크 페달을 밟으면 자동차의 브레이크는 마찰력을 이용해 바퀴의 운동을 방해하여 속도를 낮춥니다. 이때, 운동에너지는 열에너지로 바뀝니다. 두 면이 서로 맞닿으면 그 즉시 마찰력이 발생합니다. 마찰력에는 정지마찰력 (정지 중인 물체와 면)과 운동마찰력 (이동 중인 물체와 면) 두 종류가 있으나 프로그래밍 목적에 맞는 운동마찰력만 배워 봅시다.
다음 그림으로 마찰력 공식을 더 쉽게 이해해 봅시다.
마찰력 = −1µN*v 공식과 함께 썰매 타는 사람
이제 이 공식을 마찰력의 두 성분 (방향과 크기)으로 나누어 알아봅시다. 위 그림을 보면 마찰력은 속도와 방향이 반대입니다. 공식에서 나와있는 1v^ 부분, 즉 -1 곱하기 속도의 단위 벡터는 마찰력이 속도와 방향이 반대라는 것을 말해줍니다. ProcessingJS에서 이것은 속도 벡터를 정규화 시킨 다음 -1로 곱해주는 것을 의미합니다.
var friction = velocity.get();
friction.normalize();
// 마찰력의 방향을 알아봅시다 
// (속도와 반대 방향의 단위 벡터)
friction.mult(-1);
여기서 두 개의 단계를 추가해 봅시다. 첫 번째, 실수로 속도 벡터의 방향을 뒤집어 놓는 것을 방지하기 위해 벡터를 복사합니다. 두 번째, 벡터를 정규화합니다. 정규화를 하는 이유는 마찰력의 크기는 이동속도와 관계가 없고 크기를 1로 시작하면 나중에 크기를 바꿔줄 때 더욱 편리하기 때문입니다.
공식에서 마찰력의 크기는 μN 으로 정의됩니다. 앞에 있는 그리스 문자 뮤는 마찰계수 를 나타냅니다. 마찰계수는 어떤 면 고유의 마찰력으로 그 종류에 따라 수치가 다른 값입니다. 값이 클수록 마찰력이 더 강해지고 값이 작을수록 마찰력은 더 약해집니다. 예를 들어 얼음은 사포보다 훨씬 더 낮은 마찰계수를 가지고 있습니다. ProcessingJS 의 세계에서는 마찰계수를 원하는 정도로 설정할 수 있습니다.
var c = 0.01;
그다음 부분 N수직항력을 나타냅니다. 물체가 서로에 닿을 때 발생하는 접촉력입니다. 좀 더 정확히 N은 접촉력의 수직 요소라고 할 수 있습니다.
도로를 달리는 자동차를 상상해 봅시다. 자동차는 도로를 밀고 있고 뉴턴의 제3법칙에 따르면 도로도 자동차를 밀고 있습니다. 이것이 수직항력입니다. 물체가 수평으로 움직일 때 수직항력은 질량에 중력을 곱한 값으로 Fn=mg라고 씁니다. 이 말은 가벼운 스포츠카는 상대적으로 작은 수직항력을 가하고, 따라서 큰 트레일러보다 작은 마찰력을 경험한다는 뜻입니다.
그러나 위 그림에서 물체는 일정 각도로 표면을 따라 움직이고 있고, 그러면 수직 항력을 계산하는 것이 약간 더 복잡합니다. 중력과 방향이 동일하지 않기 때문입니다. 이 때문에 각도와 삼각법에 대해 알아야 합니다.
지금은 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를 적용합니다.