2014년 2월 26일 수요일

[일기]Box2D, Force and Impulse.

힘과 충격량.

 물체를 움직이고자 할 때는 에너지가 필요하며 이는 힘에서 나온다.

 Box2D에서는 힘과 추진력(충격량) 두가지를 제공한다.

 힘은 서서히 같은 힘을 가하는 것이며, 충격량은 해당 강체의 질량, 적용되는 다른 힘들을 모두 무시하고 독립적으로 큰 힘이 가해진 것과 같은 효과를 나타낼 때와 같이 일순간에 큰 힘을 가한다. 표현은 이렇게 하였으나 충격량은 사실, 물체의 운동량의 변화량이다. 충격량을 적용시킨다는 것은 물체의 운동량을 변화시키겠다는 뜻이다. 이 때 가장 두드러지게 나타나는 변화가 속도이다. 그렇기에 위와 같이 표현하였다.

 F = ma 이며 따라서 힘을 시간에 대해 적분하면 결과로 충격량(아마도? 기억이...)을 얻는다. 아래에서 언급했지만 힘을 가하는 시간이 일정수준 지났을 때 그 효과가 충격량을 주었을 때의 효과와 같은 것은 이러한 이유에서이다.

 강체의 메서드들로 힘을 가할 수 있다.

 pBody->ApplyForce( b2Vec2(0, 100), pBody->GetWorldCenter(), true);

 pBody->ApplyLinearImpluse( b2Vec2(0, 50), pBody->GetWorldCenter(), true);

각 인자의 의미는 처음 값은 힘의 크기와 방향이며, 두번째는 힘이 가하여질 위치, 셋째는 수면 상태에 있는 강체가 힘 적용 대상이 되는지 아닌지에 관한 여부다. 이것이 false면 수면 상태의 강체에게는 힘이 가해지지 않는다.

 GetWorldCenter()메서드는 강체의 질량 중심점을 의미한다. 즉 위 코드는 질량의 중심에 힘을 가하겠다는 뜻이다.

 이를 GetWorldPoint( b2Vec2(12, 0) ) 의 형태로 변경하여 힘 적용 지점을 강체의 원점을 기준으로 지정할 수 있다. 이 경우 질량의 중심에 힘이 가해지지 않았으므로 토크에 의해 강체는 회전력을 가질 수도 있다. 주의할 점은 강체 기준 좌표라는 것이다. 절대 고정체에 대한 좌표가 아님을 인지하여야 한다.

 위 메서드를 통해 특정 키(힘은 k키, 충격량은 l키와 같이)를 눌렀을 때 힘이 가해지는 경우와 충격력이 가해지는 경우를 실험해 보았다. 그런데 k키를 눌러도 힘은 전혀 가해지지 않는 듯 보였다(물체가 가만히 있네...). 알아보니 키 콜백은 눌러질 때만 적용이 되며, 힘은 한 번 적용되면 끝이었다. 한 스텝을 밟을 때마다 키를 눌러야 연속으로 힘이 가해지는데 초당 60번의 스텝이 진행되는 속도를 손가락이 따라가며 키보드를 누를 수 없었다. 결과적으로 가해진 힘으로 인한 가속도는 다음 스텝에서 중력에 의해 바로 저지당했다.

 느낌상 힘은 1초간 지속적으로 가해졌을 때, 충격력과 같은 효과를 갖게 되었다. 즉, 최종 도달 속력이 같다는 뜻이다(내 생각엔 충격량은 힘에 대해 적분 구간으로 1초를 두는 것 같았다, 아니면 말고 쳇. 나중에 제대로 확인해봐야지). 이 뜻은 힘을 1초간 가해야 충격량을 적용했을 때와 같이 물체가 운동한다는 것이다. 계에 설정된 스텝간 시간 간격이 1초가 아닌 이상 그 사이사이 스텝에서 적용된 힘은 물체에 크게 눈에 띄게 영향을 주지 못한다.

 모든 단위는 초를 기준으로 한다. 그러니 한 스텝당 1초가 안 되는 상황에서 각각 적용되는 영향은 예상보다 작을 것임을 판단할 수 있다.

 토크 또한 적용이 가능하다. 토크도 서서히 가하는 것과 충격을 주는 것 두 가지 방법이 존재한다. 토크는 반드시 질량 중심으로부터 적용되는 힘이므로 힘이 가해질 위치를 지정할 필요가 전혀 없다.

 pBody->ApplyTorque( 20, true);

 pBody->ApplyAngularImpulse( 20, true);

 인자는 각각 토크의 크기, 수면 상태 강체에 대한 힘 적용 여부이다.

 이 토크도 마찬가지로 위의 것은 1초간 모든 스텝에서 지속적으로 가해지는 경우에 그 강체의 속도가 아래의 추진력을 가한 경우의 강체 속도와 같아지게 된다. 물론, 중력 등 다른 외부적인 힘들이 평형을 이룬 상태에서만 그렇다.

댓글 없음:

댓글 쓰기