# 실시간 시뮬레이션에서의 마찰 처리

#### 1. 마찰의 기본 개념

마찰은 두 물체가 접촉할 때 발생하는 저항력으로서, 물체의 상대 운동을 저지하거나 지연시키는 힘이다. 마찰은 주로 두 가지 형태로 나뉜다: 정지 마찰 (static friction)과 운동 마찰 (kinetic friction).

정지 마찰은 물체가 움직이기 전, 접촉면 사이에서 발생하는 최대 저항력을 의미한다. 운동 마찰은 물체가 이미 움직이고 있을 때 접촉면 사이에서 발생하는 저항력을 말한다.

#### 2. 마찰 모델

실시간 시뮬레이션에서의 마찰 모델은 일반적으로 다음의 수식들을 통해 표현된다. 정지 마찰과 운동 마찰의 모델은 다음과 같다:

**정지 마찰 모델**

$$
\mathbf{f\_s} \leq \mu\_s \mathbf{N}
$$

여기서:

* $\mathbf{f\_s}$는 정지 마찰력
* $\mu\_s$는 정지 마찰 계수
* $\mathbf{N}$는 법선 반응력 (일반적으로 접촉면의 수직 방향력)

**운동 마찰 모델**

$$
\mathbf{f\_k} = \mu\_k \mathbf{N}
$$

여기서:

* $\mathbf{f\_k}$는 운동 마찰력
* $\mu\_k$는 운동 마찰 계수

#### 3. 마찰력 계산

실시간 시뮬레이션에서는 각 물체 간의 접촉점에서 발생하는 마찰력을 계산해야 한다. 이 마찰력은 물체의 움직임을 저지하거나 느리게 만드는 역할을 한다. 마찰력 계산의 과정은 다음과 같다:

**접촉점 결정**

먼저 두 물체 사이의 접촉점을 결정해야 한다. 접촉점의 수와 위치는 시간이 지남에 따라 변할 수 있기 때문에, 이는 실시간으로 업데이트되어야 한다.

#### 4. 정지 마찰 계산

**최대 정지 마찰력 계산**

접촉점에서의 최대 정지 마찰력 ($\mathbf{f\_s}$)은 다음과 같이 계산된다:

$$
\mathbf{f\_{s, max}} = \mu\_s \mathbf{N}
$$

**정지 마찰력 적용**

물체가 정지 상태에 있고, 외력에 의한 충격량이 $\mathbf{f\_{s,max}}$ 이내일 경우, 물체는 움직이지 않는다. 이 때의 실질적인 정지 마찰력은 적용된 외력에 대해 저항하는 만큼만 발생하며, 이는 다음과 같다:

$$
\mathbf{f\_s} = -\mathbf{F\_{ext}}
$$

여기서:

* $\mathbf{F\_{ext}}$는 물체에 가해진 외력이다.

만약 외력이 최대 정지 마찰력을 초과할 경우, 물체는 운동하게 되고, 운동 마찰이 적용된다.

#### 5. 운동 마찰 계산

운동 마찰 계산은 상대적으로 간단하다. 접촉점에서의 운동 마찰력($\mathbf{f\_k}$)은 다음과 같이 계산된다:

$$
\mathbf{f\_k} = \mu\_k \mathbf{N}
$$

운동 마찰력은 항상 상대 운동 방향에 반대 방향으로 작용한다. 이는 물체의 속도 벡터를 이용해 직관적으로 이해할 수 있다.

#### 6. 수치적 접근

실시간 시뮬레이션에서 마찰 모델을 수치적으로 처리하는 방법은 다양하다. 일반적인 방법으로는 시간 간격 ($\Delta t$)을 이용해 작은 시간 단위로 시뮬레이션을 진행하면서 마찰력을 업데이트하는 방식이 있다.

**시뮬레이션 루프**

1. 현재 상태 업데이트 (위치, 속도 등)
2. 법선 반응력 $\mathbf{N}$ 계산
3. 정지 마찰과 운동 마찰의 임계값 비교
4. 정지 마찰 또는 운동 마찰력 적용
5. 속도 및 위치 업데이트

#### 7. 물리 엔진에서의 마찰 구현 사례

**A. 단순한 물리 엔진에서의 구현**

단순한 물리 엔진에서는 마찰력을 구현하는 과정은 아래와 같은 단계로 이루어진다:

1. **법선 반응력 계산**:

   ```python
   normal_force = mass * gravity
   ```
2. **정지 마찰력 계산과 적용**:

   ```python
   static_friction_force_max = static_friction_coefficient * normal_force
   if external_force_magnitude <= static_friction_force_max:
       friction_force = -external_force  # 물체는 움직이지 않음
   else:
       # 물체가 운동을 시작함
       friction_force = -static_friction_force_max * (external_force / external_force_magnitude)
   ```
3. **운동 마찰력 계산과 적용**:

   ```python
   kinetic_friction_force = kinetic_friction_coefficient * normal_force
   friction_force = -kinetic_friction_force * (velocity / velocity_magnitude)
   ```

**B. 복잡한 물리 엔진에서의 구현**

복잡한 물리 엔진에서는 접촉점 간의 상호작용을 더욱 정밀히 다루며, 여러 접촉점에서 발생하는 마찰과 법선 반응력을 종합하여 시뮬레이션을 수행한다.

1. **접촉점의 결정**: 충돌 감지 알고리즘 (예: GJK, MPR 등)을 사용해 접촉점을 찾아낸다.
2. **접촉 상황 분석**: 각 접촉점에서의 법선 반응력 $\mathbf{N}$과 각각의 마찰력 $\mathbf{f\_s}$ 또는 $\mathbf{f\_k}$을 계산한다.
3. **마찰력 합산**: 여러 접촉점 사이에서 발생하는 마찰력을 모두 합산하여 최종적인 마찰력을 결정한다.
4. **시뮬레이션 업데이트**: 마찰력을 포함한 모든 힘을 종합하여 물체의 위치와 속도를 업데이트한다.

```python
for contact_point in contact_points:
    normal_force = compute_normal_force(contact_point)
    if object_is_static:
        static_friction_force_max = static_friction_coefficient * normal_force
        if external_force_magnitude <= static_friction_force_max:
            friction_force = -external_force
        else:
            kinetic_friction_force = kinetic_friction_coefficient * normal_force
            friction_force = -kinetic_friction_force * (velocity / velocity_magnitude)
    
    total_friction_force += friction_force

update_position_and_velocity(total_friction_force, delta_time)
```

***

마찰은 물리 엔진에서 물체의 운동을 예측하는 데 중요한 역할을 한다. 정지 마찰과 운동 마찰의 정확한 모델링 및 계산을 통해 현실적인 시뮬레이션 결과를 얻을 수 있다. 단순한 물리 엔진에서의 구현은 상대적으로 쉬운 편이나, 복잡한 시뮬레이션에서는 여러 접촉점의 상호작용을 고려해야 하므로 보다 정밀한 접근이 필요하다.

마찰 모델을 제대로 이해하고 정확히 구현하는 것은 물리 엔진의 성능과 정확성을 높이는 데 중요한 요소이다.
