본문 바로가기
파이썬으로 배우는 지구과학

파이썬과 원 방정식을 이용하여 태양계 행성의 공전궤도 그리기(feat. 파이썬으로 원 그래프 그리기)

by 0대갈장군0 2022. 3. 12.
반응형

이번 포스팅에서는 파이썬을 이용해 태양계 행성의 공전궤도를 그려보는 방법을 소개해 볼까 합니다.

 

대부분의 서적에서 태양계 행성의 공전궤도는 숫자로만 소개할 뿐, 직접 그림으로 그리는 경우는 잘 없습니다. 모르긴 몰라도 태양계 행성의 공전궤도를 그림으로 표현하려면 중요도에 비해 책 지문의 양을 너무 많이 차지해서 그런게 아닐까 생각합니다. 그러다보니, 실제 스케일을 무시하고 단순히 수, 금, 지, 화, 목, 토, 천, 해 순으로 단순하게 나열하기만 하는 경우가 많습니다. 사실 이것이 문제인데, 단순히 표에서 숫자로만 나열하다보면 수, 금, 지, 화성이야 그렇다 하더라도 목, 토, 천, 해로 갈수록 행성들이 얼마나 멀리 떨어져 있는지 감이 잘 오지 않는 경우가 많습니다.

 

하지만 실제로 이 아이들을 종이에 그리려면 모르긴 몰라도 종이가 매우 커야 할겁니다. 천왕성이나 해왕성의 경우 지구 공전궤도에 비해 엄청나게 크기 때문에, 천왕성 해왕성을 중심으로 그리다보면 지구형 행성을 그리기 너무 어렵고, 반대로 지구형 행성을 중심으로 그리다보면, 천왕성이나 해왕성은 공전궤도가 너무 커서 그리기가 엄청 힘들 겁니다.

 

하지만 파이썬을 이용하면 여기에서 비교적 자유롭습니다. 그래서 여기서는 파이썬으로 간단한 코드를 짜서 행성의 공전궤도를 그려볼까 합니다.

 

그리기 전 우선

1) 실제 태양계 행성의 공전궤도는 타원이지만, 원으로 가정하겠습니다. 공전궤도가 엄밀히 말하면 타원이긴 하지만, 거의 원에 가깝기 때문입니다.

 

2) 원을 그리는 다른 간단한 코드도 있기야 하지만, 여기서는 다른 라이브러리 사용을 최소화 하기 위해 수학적 방정식을 이용할 예정입니다.

 

수학에서 익히 보는 원 방정식은 아래와 같은 형태입니다.

이 방정식을 이용해도 되는데, y에 대한 형태로 식을 바꿔야 하고, 해를 +- 두 개로 나눠 출력해 줘야하기 때문에, 단순히 원을 그리기 위해서는 오히려 복잡합니다. 그래서 여기서는 삼각함수를 이용하고자 합니다. 삼각함수를 이용하면 아래와 같이 간단히 표현할 수 있습니다.

수학 관련 포스팅이 아니니 이 식에 대한 설명은 생략하고, 이렇게 하면 r이 원의 반지름이 됩니다.

 

기본적으로 필요한 라이브러리는 많이들 사용하는 matplotlib.pyplot와 math입니다. numpy는 기호에 따라 써도 되고 안써도 됩니다.

반응형

우선 필수 라이브러리를 호출합니다.

다음으로 리스트형 데이터를 추출합니다. 요 리스트형 데이터는 행성의 반지름으로 사용할 아이들인데, 

수성, 금성, 지구, 화성, 목성, 토성, 천왕성, 해왕성의 공전궤도 반지름을 사용할 것입니다. 명왕성은 태양계 행성에서 퇴출됬지만, 얼마나 멀리 있는지 보고자 같이 넣었습니다.

수성(AU) 금성(AU) 지구(AU) 화성(AU) 목성(AU) 토성(AU) 천왕성(AU) 해왕성(AU) 명왕성(AU)
0.4 0.7 1 1.5 5.2 9.6 19.2 30.1 40

우선 전체를 다 그려보지 않고, 화성까지만 그려보겠습니다. 

 

이렇게 리스트형 데이터까지 불러온 코드는

이제, 그래프의 크기를 결정하고, for문을 이용해 리스트형 데이터를 하나씩 반지름에 집어 넣을 것입니다. 여기까지 코드는

요 코드에 대한 설명을 좀 하겠습니다.

1) plt.figure(figsize=(10,10)) 은 단순히 그래프 크기 지정이니 생략

 

2) angle=np.arange(0,360) angle이라는 변수를 만들어 0에서 360.1까지를 1 간격으로 출력하라는 명령어를 썼습니다. 360.1이라고 한 이유는 360.1로 안하고 그냥 360으로 하면, 359까지만 출력하여 그래프에 작은 공백이 생기기 때문입니다. 360.1로 해야 360까지 계산합니다.

 

3) for 문 내부에 radius라는 데이터를 순서대로 r에 집어넣으라는 코드를 짠 것인데, 계산을 하기전 x와 y라는 빈 리스트를 만들었습니다. 이유는 그 아래 for문에서 원 방정식에 r을 순서대로 계산한 뒤, x,y라는 빈 리스트에 집어넣을 것이기 때문입니다.

 

4) for theta in angle: 에서 바로 이 작업을 합니다.

   x.append(r*math.cos(math.radians(theta))) 라고 하면, math라는 라이브러리에 있는 cos와 radians를 이용해 원 방정식의 해를 계산하는데, radians를 쓴 이유는 theta값을 radian으로 변환해야 삼각함수 해를 계산할 수 있기 때문이며, math.cos이라 쓴 이유는, 이렇게 하면 math라는 라이브러리를 이용해 cos 값을 계산할 수 있기 때문입니다. 이렇게 계산한 결과를 x.append라는 명령어로 x라는 빈 리스트에 추가하게 됩니다. y도 마찬가지입니다.

 

  이렇게 첫 번째 r 값인 r=0.4에 대한 계산이 끝나면, 다시 두 번째 r값인 0.7을 계산합니다. 여기서 잘 보면, 다시 x,y를 빈 리스트로 선언하게 됩니다. 그리고 새롭게 선언한 x,y라는 빈 리스트에 삼각함수 계산 값을 새롭게 집어넣기 시작합니다.

 

이렇게 하지 않고, 빈 리스트를 for문 밖으로 빼 버리면 0.4,0.7,1,1.5에 대한 계산 결과가 x,y 리스트에 차곡차곡 쌓여 버리기 때문에 최종 그래프에 알 수 없는 가로줄이 같이 생겨버립니다. 반드시 x, y 빈 리스트를 for문 안에 넣어줍시다.

 

그리고, r이 0.4,0.7,1,1.5 인 4개의 서로 다른 그래프를 하나의 모눈종이에 4번 그려야 하는 plt.plot(x,y)역시 for문 안에 넣어 줍시다. plt.plot를 for문 밖으로 빼 버리면 r=1.5인 그래프 하나만 출력합니다.

 

여기까지 이해하셨으면 이제 90%가 끝났습니다. 나머지 코드는 단순히 그래프를 얘쁘게 꾸며주기 위한 코드입니다. 저의 경우 아래와 같이 했습니다.

여기까지 하면 최종 결과물은 아래와 같습니다.

 

이제 나머지 행성, 목, 토, 천, 해, 명도 그려봅시다.

모든 행성의 공전궤도가 완성되었습니다. 수금지화에 비해 목토천해명은 터무니 없이 멀리 있죠?

 

여기에다가 최근에 태양계를 벗어난 보이저호의 위치를 표시해 보겠습니다. 2022년 현재 보이저 1호의 위치는 약 142AU, 보이저 2호의 위치는 약 119AU에 있다 합니다. 이를 표시해 보면

마지막으로 오르트(오오트) 구름의 위치를 집어 넣으면 태양계 행성들의 궤도는 더욱 보잘것 없어집니다. 알려진 오르트 구름의 반지름이 100,000~200,000AU 이니, 이것의 평균으로 대략 150,000AU를 집어넣어 보겠습니다. 숫자만 보아도 어마어마 합니다. 아마도 태양계 행성들의 궤도는 모두 점이 되어버릴 것 같은데, 그래도 아직 1pc 거리도 되지 않았습니다.

태양계 행성들의 공전 궤도는 모두 점이 되어 보이지 않습니다. 

 

이걸 생각해 보면 태양의 중력이 정말 멀리까지 영향을 미치고 있구나 하는 사실이 새삼 놀랍습니다.

반응형

댓글