두 물체가 충동한다는 것은 무엇을 의미하는가? 충돌은 동일한 시간에 특정한 지점에서 일어나며 상대에게 힘을 작용하는 행위이다. 동시에 작용과 반작용의 법칙에 의해 자신에게도 반대방향의 힘이 가해진다. 이러한 원리로부터 충돌의 처리는, 충돌의 검출(collision detection) -> 힘의 작용 이라 파악할 수 있다. (설명을 간단히 하기 위해 충돌하는 두 물체는 모두 강체라고 가정한다.)
충돌의 검출엔 '접촉점(contact point)'과 '접촉법선(contact normal)'의 파악이 중요하다. 접촉점에 어떤 접촉노멀을 가지로 충돌하냐에 따라 충돌 후 물체가 움직이거나 회전하며 움직이는 결과를 보이는 것이다. 다음 그림을 보자.
충돌은 두 물체 1, 2에 대해 서로 다른힘(방향이 반대고 크기가 같다)으로 작용한다. 따라서 시간 [math]t[/math]에서 물체1의 접촉점을 [math]s_1(t)[/math], 물체2의 접촉점을 [math]s_2(t)[/math]라 표현한다. 그리고 접촉노멀은 물체1의 관점에서 접촉노멀로 [math]n[/math]로 표현하는 유닛벡터이다(보라색벡터).
충돌을 처리하는것을 '충돌해결(collision resolution)'이라 한다. 충돌해결에 앞서 두 접촉점의 속도(갈색벡터가 물체1의 접촉점속도 [math]\dot{s_1}(t)[/math], 초록벡터가 물체2의 접촉점속도 [math]\dot{s_2}(t)[/math] )에 대한 상대속도 [math]\dot{s_1}(t) - \dot{s_2}(t)[/math] (빨간색 벡터)를 보자. 상대속도가 접촉노멀에 사영되었을 때 양의 값을 가진다면 충돌이 이미 해결된 시점이다. 반면 음의값을 가진다면 충돌해결이 필요한 시점임을 알 수 있다. 값이 0이라면 '휴지상태(resting state)'라 하여 조금 특별한 처리가 필요하다. 우리가 처리해야할 상태는 충돌상태이므로,
[math!]c = n \cdot \left( \dot{s_1}(t) - \dot{s_2}(t) \right)[/math!]
에서 [math]c<0[/math]일 때 만을 고려한다. 위 그림은 충돌해결이 필요한 상황이다.
충돌로 인한 힘은 두 물체에게 선속도(속도라고 표현하겠다)와 각속도에 영향을 미친다. 즉, 충돌해결은 이 두 상태값의 갱신을 의미하는 것이다. 먼저 속도에 대하여 보자.
충돌이 일어날 때 '충격량(impulse)'이 발생한다. 충격량은 충돌 전 후로 운동량의 변화량을 나타내는데, 이 값이 크다는것은 충돌이 그만큼 강했다는것을 의미한다. '선충격량(linear impulse)'은 [math]\mathbf{J}[/math]로 나타내며 다음 식이 성립한다.
[math!]\mathbf{J} = \Delta \mathbf{P} = m \left( v'(t) - v(t) \right)[/math!]
여기에 두 물체 사이의 충돌에 적용되는 중요한 물리법칙, '운동량 보존(conservation of momentum)'의 법칙이 있다. 충돌하는 두 물체 사이의 운동량의 합은 충돌 전과 후가 동일하다.
[math!]m_1 v_1(t) + m_2 v_2(t) = m_1 v_1'(t) + m_2 v_2'(t)[/math!]
위 식은 다음과 같이 다시 표현될 수 있다.
[math!]m_1 \left( v_1'(t) - v_1(t) \right) = -m_2 \left(v_2'(t) - v_2(t) \right) [/math!]
이는 두 물체 사이에 작용하는 충격량이 크기는 같고 방향은 반대임을 시사한다. 이 사실로부터 충돌 후의 속도는,
[math!]\begin{aligned} v_1'(t) &= v_1(t) + \frac{\mathbf{J}}{m_1} \\ v_2'(t) &= v_2(t) - \frac{\mathbf{J}}{m_2} \end{aligned}[/math!]
임을 알 수 있다.
선충격량과 마찬가지로 '각충격량(angular impulse)' 또한 충돌 전 후의 각운동량의 변화량을 나타낸다. 그런데 재미있는 사실은 물체 위 어느 지점의 각운동량이 무게중심으로부터 지점까지의 거리벡터 [math]r_i(t)[/math]와 지점에서의 선운동량의 외적으로 표현되었던 것 처럼, 각충격량도 거리벡터와 선충격량의 외적으로 표현될 수 있다는것이다. 이러한 사실로부터 아래 식이 성립한다. (각충격량은 [math]\mathbf{K}[/math]로 표현하였다.)
[math!]\mathbf{K} = r(t) \times \mathbf{J} = \Delta L = I(t)\omega'(t) - I(t)\omega(t)[/math!]
위 식으로부터 두 물체의 갱신되는 각속도 또한 선운동량에 관한 식으로 다시 표현될 수 있다. 즉,
[math!]\begin{aligned} \omega_1'(t) &= \omega_1(t) + I_{1}^{-1}(t) \left( r_1(t) \times \mathbf{J} \right) \\ \omega_2'(t) &= \omega_2(t) - I_{2}^{-1}(t) \left( r_2(t) \times \mathbf{J} \right) \end{aligned}[/math!]
와 같이 정리된다.
이로써 충돌시 [math]\mathbf{J}[/math]만 알면 충돌 전 상태로 부터 충돌후의 속도와 각속도 모두 계산될 수 있는것이다. 이를 구하기 위해 '반발계수(coefficient of restitution)'에 대하여 설명할 필요가 있다. 반발계수는 충돌 전, 후 두 물체의 속력차이에 대한 비율이다. 즉,
[math!]C_R = \frac{v_2'(t) - v_1'(t)}{v_1(t) - v_2(t)}[/math!]
이며 [0,1]의 값을 가진다. 이와 더불어 상대속도와 접촉노멀 사이의 관계에 대하여 다시 살펴보자. 충돌 후의 [math]c[/math]는 [math]c' = n \cdot \left( \dot{s_1}'(t) - \dot{s_2}'(t) \right)[/math] 인데, 반발계수에 의해 다음과 같이 표혈될 수 있다.
[math!]c' = n \cdot \left( \dot{s_1}'(t) - \dot{s_2}'(t) \right) = -C_R c[/math!]
여기서 물체 위 한점의 속도는 [math]\dot{s}(t) = \omega(t) \times r(t) + v(t)[/math]임을 기억하자. 이로부터 두 물체에 대한 충돌지점의 속도는 다음 식을 만족한다.
[math!]\begin{aligned} \dot{s_1}'(t) &= \omega_1'(t) \times r_1(t) + v_1'(t)\\ &= \left( \omega_1(t) + I_1^{-1}(t)\left(r_1(t) \times \mathbf{J}\right)\right) \times r_1(t) + v_1(t) + \frac{\mathbf{J}}{m_1} \\ &= \omega_1(t) \times r_1(t) + v_1(t) + \left( I_1^{-1}(t)\left(r_1(t) \times \mathbf{J}\right) \right) \times r_1(t) + \frac{\mathbf{J}}{m_1} \\ &= \dot{s_1}(t) + \left( I_1^{-1}(t)\left(r_1(t) \times \mathbf{J}\right) \right) \times r_1(t) + \frac{\mathbf{J}}{m_1} \\ \dot{s_2}'(t) &= \dot{s_2}(t) - \left( I_2^{-1}(t)\left(r_2(t) \times \mathbf{J}\right) \right) \times r_2(t) - \frac{\mathbf{J}}{m_2}\end{aligned}[/math!]
이를 [math]c'[/math] 식에 적용하여 다음과 같이 다시 표현할 수 있다.
[math!]\begin{equation}\begin{split} c' &= n \cdot \left( \dot{s_1}'(t) - \dot{s_2}'(t) \right) \\ &= n \cdot \left( \dot{s_1}(t) - \dot{s_2}(t) + \left( I_1^{-1}(t)\left(r_1(t) \times \mathbf{J}\right) \right) \times r_1(t) + \left( I_2^{-1}(t)\left(r_2(t) \times \mathbf{J}\right) \right) \times r_2(t) + \frac{\mathbf{J}}{m_1} + \frac{\mathbf{J}}{m_2} \right) \\ &= n \cdot \left( \dot{s_1}(t) - \dot{s_2}(t) \right) + n \cdot \left( \left( I_1^{-1}(t)\left(r_1(t) \times \mathbf{J}\right) \right) \times r_1(t) \right) + n \cdot \left( \left( I_2^{-1}(t)\left(r_2(t) \times \mathbf{J}\right) \right) \times r_2(t) \right) + \frac{n \cdot \mathbf{J}}{m_1} + \frac{n \cdot \mathbf{J}}{m_2} \end{split}\end{equation}[/math!]
여기서 충돌시 속도변화는 접촉노멀 방향으로의 변화만 있고, 접촉면과 평행한 방향으로의 속도는 변함없음을 주목하자. 즉 [math]\mathbf{J} = jn[/math]이라 말할 수 있다. 이로부터 위 식을 다시 정리하여,
[math!]\begin{equation}\begin{split} c' &= c + j \left( n \cdot \left( \left( I_1^{-1}(t)\left(r_1(t) \times n \right) \right) \times r_1(t) \right) + n \cdot \left( \left( I_2^{-1}(t)\left(r_2(t) \times n \right) \right) \times r_2(t) \right) + \frac{1}{m_1} + \frac{1}{m_2} \right) \\ &= -C_R c \end{split}\end{equation}[/math!]
즉,
[math!]j = \frac{-\left( 1+C_R \right) c }{ n \cdot \left( \left( I_1^{-1}(t)\left(r_1(t) \times n \right) \right) \times r_1(t) \right) + n \cdot \left( \left( I_2^{-1}(t)\left(r_2(t) \times n \right) \right) \times r_2(t) \right) + \frac{1}{m_1} + \frac{1}{m_2} }[/math!]
이며 이로부터 두 물체의 충돌 후 속도와 각속도를 구할 수 있다.
두 물체의 충돌은 이렇게 마무리 되었다. 만약 동시간에 여러 충돌점이 발생한다면 모든 충돌점에서 충돌후 속도, 각속도를 계산한 후 이를 합한것이 최종 충돌 후 속도, 각속도가 된다.
참고: 3d graphics for game programming
'Graphics Note' 카테고리의 다른 글
opengl의 스크린공간은 왼손좌표계이다. (0) | 2014.04.30 |
---|---|
converting rotation quaternion into matrix, and vice versa (0) | 2014.04.21 |
rigid body collision 1 (0) | 2014.04.21 |
automatic linking the first out variable of fragment shader (4) | 2014.04.02 |
[Mathematics] quaternion interpolation (0) | 2014.03.28 |