타원과 관련한 아름다운 사실이 있어서 소개를 해 볼까 합니다.
한 점에서 타원에 그은 두 접선이 수직으로 만난다면, 그 점이 이루는 자취는 뭘까?
타원의 방정식을
$$ \frac{x^2}{a^2} + \frac{y^2}{b^2} =1 \tag{1} $$
이라 하고 우리가 관심이 있는 점을 $(X,Y)$라 합시다. 이 점을 지나는 직선의 방정식을
$$ y = m(x-X)+Y \tag{2}$$
라 쓸 수 있죠.
식(2)의 직선의 방정식이 식(1)의 타원에 접하길 기대하는 거죠. 따라서
$$ \frac{x^2}{a^2} + \frac{(m(x-X)+Y)^2}{b^2} =1 \tag{3} $$
이 중근 즉, 판별식이 0이어야 합니다.
식(3)을 정리하면
$$ b^2 x^2 + a^2 (mx +(Y-mX))^2 = a^2 b^2$$
이고, $x$에 대한 식으로 깔끔(?) 하게 정리하면
$$ (b^2 +a^2m^2)x^2 + 2m(Y-mX)a^2 x + a^2(Y-mX)^2 -a^2b^2 =0 $$
입니다. 따라서
$$D/4 = m^2 a^4(Y-mX)^2 - (b^2 +a^2m^2)[a^2(Y-mX)^2 -a^2b^2] =0 $$
이고 이것을 $m$에 대한 식으로 정리 하면
$$ (a^2 -X^2)m^2 + 2XY m + (b^2 -Y^2) =0 \tag{4}$$
이 나옵니다.
따라서, 식(4)의 $m$이 두 근 $m_1, m_2$를 가져야 하고 , 이 두 근의 곱 $m_1m_2 =-1$이 나와야 합니다.
(4)의 판별식은
$$D/4 = (XY)^2 - (a^2-X^2)(b^2- Y^2) >0$$이어야 하고, 이것을 정리하면
$$ \frac{X^2}{a^2} + \frac{Y^2}{b^2} >1$$
입니다. 즉, 점 $(X,Y)$는 타원 바깥의 점이어야 한다는 얘기죠. 그건 자명합니다. 타원 안에서는 타원에 접선을 그릴 수 없기 때문이죠.
이제 $m_1 m_2=-1$을 이용하면 근과 계수와 이 관계에 의해서
$$ -1 = m_1 m_2 = \frac{b^2-Y^2}{a^2- X^2} $$
이고
$$X^2+Y^2 = a^2+b^2$$
이 됩니다. 즉 중심이 타원의 중심과 같고, 반지름이 $\sqrt{a^2 + b^2}$인 원이 되는 것입니다.
python 차트 연습도 할 겸 위의 문제를 그려 보겠습니다.
import math
import numpy as np
import matplotlib.pyplot as plt
def plot_ellipse():
a = 2
b = 1
theta = np.linspace(0, 2 * np.pi, 100)
x = a * np.cos(theta)
y = b * np.sin(theta)
plt.plot(x, y, color='gray', linestyle='-')
radius = np.sqrt(a**2+b**2)
x_line = np.linspace(-10,10,1000)
res_x =[]
res_y=[]
for t in theta:
cir_x = radius*np.cos(t)
cir_y = radius*np.sin(t)
res_x.append(cir_x)
res_y.append(cir_y)
coeff = 2*cir_x*cir_y/(a**2 - cir_x**2)
slope1= (-1*coeff + np.sqrt(coeff**2+4))/2
slope2 = (-1 * coeff - np.sqrt(coeff ** 2 + 4)) / 2
plt.xlim([-3, 3])
plt.ylim([-3, 3])
plt.plot(x, y, color='gray', linestyle='-')
plt.plot(cir_x,cir_y,'b', marker ='o')
plt.plot(res_x, res_y, 'b')
plt.plot(x_line, slope1*(x_line-cir_x)+cir_y,'r')
plt.plot(x_line, slope2 * (x_line - cir_x) + cir_y, 'r')
plt.pause(0.05)
plt.cla()
plt.show()
if __name__ == '__main__':
plot_ellipse()
code를 간단히 볼까요?
a = 2 #장축을 a
b = 1 #단축을 b
theta = np.linspace(0, 2 * np.pi, 100) #theta을 0에서 2π까지 돌리면서
x = a * np.cos(theta) #타원의 x좌표를 설정
y = b * np.sin(theta) #타원의 y좌표를 설정
plt.plot(x, y, color='gray', linestyle='-') #타원위의 점을 plotting한다.
식(1)의 타원의 방정식은
$$ x= a\cos\theta, y = b\sin\theta~~,~~0\leq \theta\leq 2\pi$$
로 매개변수 방정식으로 쓸 수 있습니다.
radius = np.sqrt(a**2+b**2) #문제의 결과는 반지름이 sqrt(a^2+b^2)인 원이라 반지름을 설정
x_line = np.linspace(-10,10,1000) #접선을 그리기 위해 x좌표 설정
res_x =[] #문제의 결과인 원의 x좌표를 저장할 list
res_y=[] #문제의 결과인 원의 y좌표를 저장할 list
for t in theta:
cir_x = radius*np.cos(t) #원의 x좌표
cir_y = radius*np.sin(t) #원의 y좌표
res_x.append(cir_x) #원의 x좌표를 res_x에 추가
res_y.append(cir_y) #원의 y좌표를 res_y에 추가
coeff = 2*cir_x*cir_y/(a**2 - cir_x**2) #아래 설명 참조
slope1= (-1*coeff + np.sqrt(coeff**2+4))/2 #아래 설명 참조
slope2 = (-1 * coeff - np.sqrt(coeff ** 2 + 4)) / 2 #아래 설명 참조
plt.xlim([-3, 3]) #그래프의 x좌표를 -3과 3사이로 설정
plt.ylim([-3, 3]) #그래프의 y조표를 -3과 3사이로 설정
plt.plot(x, y, color='gray', linestyle='-') #타원을 그림
plt.plot(cir_x,cir_y,'b', marker ='o') #원위의 점을 o라는 marker를 사용하여 그림
plt.plot(res_x, res_y, 'b') #시간이 지나며 갱신되는 원의 자취를 그림
plt.plot(x_line, slope1*(x_line-cir_x)+cir_y,'r') #접선1을 그림
plt.plot(x_line, slope2 * (x_line - cir_x) + cir_y, 'r') #접선2를 그림
plt.pause(0.05) #0.05초만큼의 정지화면을 주어 그래프의 animation을 효과를 줌
plt.cla() #화면 지우는 함수
수식(4)를 좀 더 간략히 쓰면
$$ m^2 + \frac{2XY}{a^2-X^2} m -1 = 0$$
이 됩니다.
$$ c= \frac{2XY}{a^2-X^2}$$ 라고 두면, $m^2 + cm-1=0$의 두 근은
$$ m_1, m_2 = \frac{-c\pm\sqrt{c^2+4}}{2}$$
이므로 위의 code의 coeff, slope1, slope2를 설명할 수 있습니다.
결과는 아래와 같습니다. scale 때문에 원이 아닌 것 같이 보이네요.
댓글