실린더와 실린더의 충돌 검사 알고리즘은 주로 두 실린더의 위치, 방향, 반지름, 높이를 고려하여 충돌 여부를 판별하는 방식으로 구현된다. 이 알고리즘의 일반적인 단계는 다음과 같다.
1. 실린더 모델 정의
- 각 실린더는 아래와 같은 파라미터로 정의된다:
- 위치 (P1, P2): 실린더의 중심 위치.
- 방향 벡터 (D1, D2): 실린더의 축 방향 벡터.
- 반지름 (R1, R2): 실린더의 반지름.
- 높이 (H1, H2): 실린더의 높이.
2. 축 방향 거리 계산
두 실린더의 축이 평행하지 않으면, 각 실린더 축에서 수직 거리를 계산해야 한다. 축이 평행하지 않으면 실린더 간의 축 방향 벡터에 대한 최소 거리를 구하는 식을 사용한다.
- 두 실린더의 축 벡터 D1과 D2가 있을 때, 그 사이의 최소 거리 벡터는 두 실린더 축에 수직인 벡터를 구함으로써 계산된다. 이를 벡터 수학적으로 나타내면:
\text{distance} = \frac{|(P2 - P1) \cdot (D1 \times D2)|}{|D1 \times D2|}
여기서 P1과 P2는 각 실린더의 중심 좌표이고, D1과 D2는 각 실린더의 축 방향 벡터이다.
3. 축 거리 비교
두 실린더가 축 방향 거리에서 겹치지 않는다면 충돌하지 않음을 빠르게 확인할 수 있다. 즉, 실린더의 중심에서 반지름까지의 거리가 충분히 크면 충돌하지 않는다:
\text{충돌 조건}: \text{distance} \leq (R1 + R2)
여기서 R1과 R2는 각 실린더의 반지름이다.
4. 높이 비교
축 방향에서 충돌이 의심되는 경우, 실린더의 높이로 충돌 여부를 확인할 수 있다. 각 실린더의 중심에서 해당 축을 따라 상하로 이동한 위치가 겹치는지 확인한다.
- 실린더의 두 끝점(상단과 하단)의 좌표를 계산한 후, 이 끝점들이 서로 겹치는지 확인한다. 상하로 겹치는 경우는 두 실린더가 높이에서 충돌하는 것을 의미한다.
5. 최종 충돌 판단
축 방향 거리와 높이 비교가 모두 충돌로 판별될 경우, 두 실린더는 충돌하고 있다고 판단할 수 있다.
의사 코드
bool CylinderCollision(Vector3 P1, Vector3 D1, float R1, float H1,
Vector3 P2, Vector3 D2, float R2, float H2) {
// 1. 축 방향 거리 계산
Vector3 diff = P2 - P1;
Vector3 crossDir = Cross(D1, D2);
float distance = Abs(Dot(diff, crossDir)) / Length(crossDir);
// 2. 반지름 비교
if (distance > (R1 + R2)) {
return false; // 충돌하지 않음
}
// 3. 높이 비교
// 각 실린더의 끝점 계산
Vector3 P1_top = P1 + (D1 * (H1 / 2));
Vector3 P1_bottom = P1 - (D1 * (H1 / 2));
Vector3 P2_top = P2 + (D2 * (H2 / 2));
Vector3 P2_bottom = P2 - (D2 * (H2 / 2));
// 상단과 하단 좌표 비교로 충돌 여부 결정
if ((P1_top < P2_bottom) || (P1_bottom > P2_top)) {
return false; // 충돌하지 않음
}
return true; // 충돌
}
위 알고리즘은 두 실린더의 축이 평행하지 않은 경우에도 적용 가능하며, 축이 평행한 경우에도 축 방향 거리 계산을 통해 정확한 충돌 여부를 판단할 수 있다.