반응형

두 곡선의 교차점에 대응하는 x, y좌표를 구할 수 있는 Python 예제 코드입니다.

 

2021. 11. 30 - 최초작성

 

 

실행 결과입니다. 두 곡선의 교점을 초록색 점으로 표시해주고 있습니다. 

 

 

터미널에서 교차점의 x,y 좌표를 확인할 수 있습니다.

 

[(1.2831976623728205, -0.283620905396323), (4.425039547130342, 0.2818828030413486), (7.566358178278255, -0.281334885867327)]

 

 

전체 소스 코드입니다. 

# -*- coding: utf-8 -*-

# 원본 코드 - https://stackoverflow.com/a/59120343
import numpy as np
from matplotlib import pyplot as plt


# x 좌표 범위를 지정합니다.0 ~ 10 사이에 40개를 생성합니다.
x = np.linspace(0, 10, 40)

# 두 곡선을 위한 y좌표를 생성합니다. 위에서 생성한 x좌표 범위내에서 생성됩니다. 
curve1 = -np.cos(x+10)
curve2 = -np.cos(x)


fig, ax = plt.subplots()

# 두 곡선을 각각 파란색, 빨간색으로 그립니다. 
ax.plot(x, curve1,'b')
ax.plot(x, curve2,'r')


intersections = []
prev_dif = 0
x0, prev_c1, prev_c2 = None, None, None
for x1, c1, c2 in zip(x, curve1, curve2):  # 현재 x좌표에 해당되는 두 곡선의 y 좌표가 각각 c1, c2입니다.
    new_dif = c2 - c1 # 현재 x 좌표에서 두 곡선의 y좌표의 차이입니다.
    if np.abs(new_dif) < 1e-12: # 현재 x 좌표에서 두 곡선의 y좌표 차이가 0인 경우입니다. 즉 두 곡선이 교차하는 지점입니다. 차이가 0인 경우로 체크하지 않고 이렇게 하는군요.
        intersections.append((x1, c1))
    elif new_dif * prev_dif < 0:  # 현재 x 좌표(x1)에서 두 곡선의 y좌표 차이가 이전 x좌표(x0)에서 계산한 두 곡선의 y좌표 차이의 부호와 다른 순간입니다. 즉 부호가 바뀌는 순간입니다. 
                                  # 즉 현재 x 좌표(x0)과 이전 x 좌표(x1)사이에 두 곡선의 교점이 있는 것을 알 수 있습니다.  
        # 현재 x 좌표(x0)과 이전 x 좌표(x1)사이에 두 곡선의 y값이 같아지는 x 좌표를 찾기 위해 선형 보간(linear interpolation)을 수행합니다.  
        # 직선 [(t0, prev_c1), (t1, c1)]과 직선 [(t0, prev_c2), (t1, c2)]의 교차점입니다. 
        denom = prev_dif - new_dif
        intersections.append(((-new_dif*x0  + prev_dif*x1) / denom, (c1*prev_c2 - c2*prev_c1) / denom))
    x0, prev_c1, prev_c2, prev_dif = x1, c1, c2, new_dif

print(intersections) # 두 곡선의 교점 리스트를 출력합니다.

ax.plot(*zip(*intersections), 'go', alpha=0.7, ms=10) # 두 곡선의 교점을 그래프에 녹색점으로 출력합니다. 
plt.show()
반응형

해보고 확인한 것을 문서화하여 기록합니다.
최소 일주일에 한번 이상 포스트를 하려고 노력중입니다.

부족함이 있지만 도움이 되었으면 합니다.
잘못된 부분이나 개선점을 알려주시면 감사하겠습니다.



포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
시간날때 마다 이전 포스트가 문제 있는지 확인을 해보려고 노력하고 있습니다.
질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

">