카테고리 없음

[Geometry] 두 선분의 교점 및 교차 여부

gyeongtiger 2024. 12. 21. 23:20

자율주행 연구를 하다 보면 기하학적 문제를 해결해야 하는 경우가 종종 있습니다. 그중 하나가 두 선분의 관계입니다. 두 선분의 교점, 교차 여부를 확인하는 방법에 대해 알아보겠습니다.

 

 

1. 직선의 방정식

두 점이 주어졌을 때, 직선의 방정식을 x가 아닌 두 점에 대한 거리 비율 t로 표현할 수 있습니다.

 

2. 교점 구하기

두 직선의 교점을 찾기 위해 위 두 식을 연립하면 아래와 같이 나타낼 수 있습니다.

이를 풀면 다음과 같은 식이 유도됩니다:

여기서 구한 t를 P(t) 식에 대입하면 교점 Q의 좌표를 찾을 수 있습니다. 

 

 

3. 교차 여부 확인

교차 여부는 수평 여부 확인내분 확인 2가지 과정으로 구성됩니다. 

 

3-1) 수평 여부 확인

두 직선이 수평인 경우 교차하지 않습니다. 수평 여부는 외적을 통해 확인할 수 있으며, 수평인 경우 두 벡터의 외적의 크기가 0이 됩니다.

이 값이 t의 분모와 동일합니다. 따라서 이 값이 0일 경우 3-2)로 가지 않도록 예외 처리를 해줘야 합니다.

 

3-2) 내분 확인

위에서 유도한 식으로 t와 s를 계산합니다. t, s가 모두 0~1 사이 범위에 있다면 두 선분은 교차하는 겁니다.

 

 

 

def calculate_intersection(p1, p2, q1, q2):
    """
    두 선분의 교차 여부와 교점을 계산합니다.

    Parameters:
        p1, p2: 선분 1의 시작점과 끝점 (x1, y1), (x2, y2)
        q1, q2: 선분 2의 시작점과 끝점 (x3, y3), (x4, y4)

    Returns:
        (bool, (float, float) or None): 교차 여부와 교점 좌표
    """
    x1, y1 = p1
    x2, y2 = p2
    x3, y3 = q1
    x4, y4 = q2

    # 선분 방향 벡터 계산
    denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)

    if abs(denominator) < 1e-6:  # 두 선분이 평행함
        return False, None

    # t와 s 계산
    t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denominator
    s = ((x1 - x3) * (y1 - y2) - (y1 - y3) * (x1 - x2)) / denominator

    # 교차 여부 확인
    if 0 <= t <= 1 and 0 <= s <= 1:
        # 교점 계산
        intersection_x = x1 + t * (x2 - x1)
        intersection_y = y1 + t * (y2 - y1)
        return True, (intersection_x, intersection_y)

    return False, None  # 교차하지 않음



# 예제 사용
p1 = (1, 1)
p2 = (4, 4)
q1 = (1, 4)
q2 = (4, 1)

is_intersect, intersection = calculate_intersection(p1, p2, q1, q2)
print(f"Do the segments intersect? {is_intersect}")
if is_intersect:
    print(f"Intersection point: {intersection}")

import matplotlib.pyplot as plt
plt.figure()
plt.plot([p1[0],p2[0]],[p1[1],p2[1]])
plt.plot([q1[0],q2[0]],[q1[1],q2[1]])
plt.show()