Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Matplotlib에서 contains_point보다 빠르게 점이 타원 내부에 있는지 확인하는 방법

개요

Matplotlib의 contains_point() 메소드는 점을 하나씩 순차적으로 판별하기 때문에 대량의 데이터 포인트를 처리할 때 속도가 느립니다. 대신 좌표 변환과 타원 방정식을 활용한 수학적 방법을 사용하면 NumPy의 벡터화 연산으로 모든 점을 한 번에 판별할 수 있어 훨씬 빠른 성능을 얻을 수 있습니다.

핵심 원리

회전된 타원 내부에 점이 있는지 확인하는 수학적 절차는 다음과 같습니다.

  • 각 점의 좌표를 타원의 중심 기준으로 평행 이동합니다.
  • 타원의 회전 각도만큼 반대 방향으로 좌표를 회전시켜 타원의 로컬 좌표계로 변환합니다.
  • 변환된 좌표를 타원의 반지름으로 정규화한 뒤, (x/a)² + (y/b)² ≤ 1 조건을 검사합니다.

이 부등식을 만족하는 점은 타원 내부에 위치한 것입니다. 이 방식은 반복문 없이 배열 연산만으로 처리되므로, 점마다 contains_point()를 호출하는 방식보다 월등히 빠릅니다.

구현 단계

  • 그림 크기를 설정하고 서브플롯 사이 및 주변 여백을 조정합니다.
  • figure와 subplot 세트를 생성합니다.
  • 축의 가로세로 비율을 동일(equal)하게 설정합니다.
  • NumPy를 사용해 x, y 데이터 포인트를 생성합니다.
  • 타원의 중심(center), 너비(width), 높이(height), 회전 각도(angle)를 초기화합니다.
  • patches.Ellipse로 타원 패치를 생성하고 axes에 추가합니다.
  • 각 점의 정규화된 반지름 값을 계산하여, 1 이하면 "red", 초과하면 "yellow"로 색상을 지정합니다.
  • scatter() 메소드로 x, y 데이터 포인트를 색상과 함께 플롯합니다.
  • show() 메소드로 그림을 화면에 표시합니다.

예제 코드

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np

plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True

fig, ax = plt.subplots(1)
ax.set_aspect('equal')

# 무작위 데이터 포인트 생성
x = np.random.rand(100) * 0.5 + 0.7
y = np.random.rand(100) * 0.5 + 0.7

# 타원 파라미터 설정
center = (0.7789, 0.7789)
width = 0.45
height = 0.20
angle = 45.

# 타원 패치 생성 후 axes에 추가
ecl = patches.Ellipse(center, width, height, angle=angle,
fill=False, edgecolor='green', linewidth=5)
ax.add_patch(ecl)

# 회전 변환에 사용할 코사인·사인 값
cosine = np.cos(np.radians(180. - angle))
sine = np.sin(np.radians(180. - angle))

# 타원 중심 기준으로 좌표 평행 이동
xc = x - center[0]
yc = y - center[1]

# 타원의 로컬 좌표계로 회전 변환
xct = xc * cosine - yc * sine
yct = xc * sine + yc * cosine

# 정규화된 반지름 제곱합 계산
rad_cc = (xct ** 2 / (width / 2.) ** 2) + (yct ** 2 / (height / 2.) ** 2)

# 내부 점은 빨간색, 외부 점은 노란색으로 지정
colors = np.array(['yellow'] * len(rad_cc))
colors[np.where(rad_cc <= 1.)[0]] = 'red'

ax.scatter(x, y, c=colors, linewidths=0.7)

plt.show()

코드 설명

코드의 핵심은 좌표 변환과 판별식입니다. 먼저 각 점에서 타원 중심을 뺀 뒤(xc, yc), 타원이 회전된 각도의 반대 방향으로 좌표축을 회전시켜(xct, yct) 마치 타원이 축에 정렬된 것처럼 만듭니다. 이후 각 좌표를 타원의 반지름으로 나누어 제곱한 값을 더하면, 그 합이 1보다 작거나 같은 점들이 타원 내부에 해당합니다. 이 조건에 따라 내부 점은 빨간색으로, 외부 점은 노란색으로 칠해집니다.

실행 결과

위 코드를 실행하면 45도로 회전된 초록색 테두리의 타원이 그려지고, 타원 내부에 있는 점들은 빨간색으로, 외부에 있는 점들은 노란색으로 표시됩니다.

Matplotlib에서 contains_point보다 빠르게 점이 타원 내부에 있는지 확인하는 방법Matplotlib에서 contains_point보다 빠르게 점이 타원 내부에 있는지 확인하는 방법