Computer Graphics

OpenGL을 이용한

태양계 공전/자전 시뮬레이션

- Solar 3D -

학    과 : 게임&멀티미디어

학    번 : 20031385.20031668

이    름 : 강유진.박지혜

담당교수 : 이병국교수님

제 출 일 : 2006년 6월15일

1. 서론

1.1 필요성, 동기

전부터 태양계의 공전과 자전에 대하여 관심이 많았는데, 태양과 태양계 내의 행성들의 움직임에 대한 궁금증과 이를 시뮬레이션해줄 수 있는 프로그램을 개발해보고 싶었다. 처음 프로젝트를 선정할때는 각 행성의 중력 계산을 통해 태양계 내 행성들이 왜 하필 이러한 궤도로 돌고 있는것인가? 에 대한 답을 얻고 싶었고, 현재와 같은 궤도에 새로운 행성이 나타난다면 각 행성들의 궤도가 어떻게 변하는지도 시뮬레이션 해보고 싶었다. 하지만, 실제물리모델을 적용하기에는 너무나 많은 변수와 전문적인 지식이 부족하여 현재 상황에서는 하기 힘든 작업이다. 또한 길지 않은 프로젝트 기간으로 인해 프로젝트의 주제를 태양계의 공전/자전에 대한 시뮬레이션 프로그램으로 정하게 되었다.

1.2 배경지식

이 프로젝트에서 사용된 각 태양계 행성들의 공전, 자전, 반지름, 태양과의 거리(타원궤도의 행성도 포함)에 대한 정보는 이미 알려진 실제정보를 통하여 제작되었다. 단, 시뮬레이션에서는 행성과 태양과의 거리가 너무 긴 관계로 실제 행성의 크기가 비율적으로 작다. 이 프로젝트의 목적은 태양계의 시뮬레이션에도 있지만 OpenGL을 사용함에도 있으므로, 그래픽 효과를 확인하기 위하여 행성의 반지름을 약 2000배 정도 확대하였다.

■ 태양계 항성/행성 기본 정보

천체	태양까지 거리	공전주기	자전주기	반지름
태양			25.40 일	696,000 km
수성	57,910,000 km	87.97 일	58.65 일	2,439 km
금성	108,200,000 km	224.70 일	243.01 일	6,052 km
지구	149,600,000 km	365.26 일	23.94 시	6,378 km
화성	227,940,000 km	686.98 일	24.62 시	3,397 km
목성	778,330,000 km	11.86 년	9.84 시	71,398 km
토성	1,426,980,000 km	29.46 년	10.23 시	60,000 km
천왕성	2,870,990,000 km	84.02 년	17.90 시	25,400 km
해왕성	4,497,070,000 km	164.77 년	19.20 시	24,300 km
명왕성	5,913,520,000 km	247.80 년	6.39 일	1,142 km

■ 행성의 궤도는 모두 타원궤도

케플러 제 1법칙 ; 타원 궤도의 법칙

행성은 태양을 하나의 초점으로 하는 타원궤도를 그리며 공전한다

이중 태양계에서 수성과 명왕성을 제외한 대부분의 행성은 원에 가까운 타원운동을 한다

■ 궤도이심률 문제

태양계의 기본 자료 중 수성과 명왕성은 궤도이심률이 너무 커 <태양까지 거리=궤도반지름>이 일정하지 않다. 이러한 문제로 명왕성의 궤도는 때로 천왕성의 궤도 안쪽으로 들어오는 경우가 있다. 또한 수성과 명왕성의 타원궤도 중심에 태양이 있지 않기 때문에 각 행성의 궤도중심점에서 태양까지의 거리를 계산해야한다.

여기에서 구할 것은 X축거리, Y축거리, 궤도중심과 태양간거리인데

긴거리+짧은거리=2*X축거리

이므로

X축거리=

궤도중심과 태양간거리=긴거리-짧은거리

Y축거리=X축거리-궤도중심과태양간거리

이므로 구하면 다음과 같다.

천체	태양까지 거리(km)				궤도중심과 태양간 거리
	가장 가까울때	가장 멀때 평균거리	X축거리	Y축거리
수 성	46,000,000	69,800,000	57,910,000	56,664,000	11,900,000
명왕성	4,433,000,000	7,365,000,000	5,899,000,000	5,713,000,000	1,466,000,000

■ 궤도평면의 각도

태양계 내의 행성들의 궤도는 비교적 같은 평면상에 있다. 단, 명왕성만이 태양계 가장 외곽에 위치한 관계로 일반적인 궤도평면과 17‘기울어져 운행을 한다.

2. 개발 시스템

2.1 시스템 구성

■ 개발환경

- Windows XP

- Visual C++ 6.0

- OpenGL

■ 클래스 구성

클래스 명	내용
CSolar3DApp	프로그램 메인 클래스(MFC)
CMainFrame	프레임 윈도우 클래스(MFC)
CChildView	프레임윈도우 안의 실제 그림을 그릴 뷰 클래스
Planet	개별 항성/행성 클래스 ( 실제 공전/자전의 처리를 한다 )
SolarSystem	태양계 클래스 ( 시간이 지남에 따라 행성들이 공전/자전을 하게한다 )
CBmp	비트맵의 텍스처를 읽기위한 클래스

■ Solar3D.exe : 시뮬레이션 실행파일

■ star?.bmp : 항성/행성/궤도선을 위한 직접 제작한 텍스처 이미지

2.2 시스템 사용 방법

■ 태양과의 거리 조절

마우스 오른쪽버튼을 누른 상태로 마우스를 위쪽으로 움직이면 태양에 가까워 진다. 축소의 경우 이와 확대의 반대로 마우스 오른쪽버튼을 누른 상태로 마우스를 아래쪽으로 움직이면 태양과 멀어진다.

■ 보는 시점 회전

다른 각도에서 보고자 하면 다음과 같이 하여 각도를 변경할 수 있다.

마우스 왼쪽 버튼을 누른 상태로

왼쪽으로 하면 절대Y축을 기준으로 반시계방향으로 회전한다.

오른쪽으로 하면 절대Y축을 기준으로 시계방향으로 회전한다.

위쪽으로 하면 절대X축을 기준으로 반시계방향으로 회전한다.

아래쪽으로 하면 절대X축을 기준으로 시계방향으로 회전한다.

■ 행성크기 변경

지나치게 축소하는 경우 행성의 크기가 너무 작아 자전하는 모습을 보기 힘들다. 그럴때는 다음과 같이 행성크기를 확대/축소한다

키보드의 ‘+’ 키를 누르면 행성크기가 커진다

키보드의 ‘-’ 키를 누르면 행성크기가 작아진다

■ 진행속도 증가/감소

시간의 단위를 증가시켜 공전을 확인하고 싶은 경우 진행속도를 증가시킬 수 있다. 행성의 자전을 천천히 보고 싶은 경우 진행속도를 감소시켜 확인할 수 있다.

키보드의 ‘1’ 키를 누르면 진행속도가 빨라진다.

키보드의 ‘2’ 키를 누르면 진행속도가 느려진다.

3. 핵심기술

3.1 핵심 기술 설명

(OpenGL)

■ 뒷면제거 : 보이지 않는 뒷면은 그리지 않도록 한다

■ 은면제거 : 은면제거를 위해 깊이검사를 한다

■ 조명 : 주변광으로 지정

태양의 경우 태양 스스로가 빛을 내는 존재이므로 조명을 받지 않도록 설정

■ 광원 : 태양의 위치에 광원을 설정하여 난반사광을 지정

■ 텍스처링 : 개별 행성에 BMP이미지의 텍스처를 입힌다

■ 더블버퍼링 : 깜빡거림을 없애기 위해 더블버퍼링을 수행한다

(시뮬레이션)

■ 자전/공전 : 각 행성이 가진 자전주기/공전주기를 절대시간 단위로 증가시킨다

■ 타원궤도 : 수성과 명왕성은 태양을 타원궤도의 한쪽 축으로 하며, 나머지 행성들은

태양을 중심으로 원궤도로 돈다

■ 궤도면 각도 : 명왕성은 궤도면이 약 17‘로 틀어져있다

■ 절대시간 : 30ms 단위로 1프레임이 수행된다.

( 1프레임에 해당하는 태양계의 시간은 SolarSystem에 설정한다 )

3.2 핵심 기술별 함수 명세

■ 뒷면제거

CChildView::Init() 에서

glEnable(GL_CULL_FACE);

■ 은면제거

CChildView::Init() 에서

glEnable(GL_DEPTH_TEST);

■ 조명

CChildView::Init() 에서

glEnable(GL_LIGHTING);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT,m_ambLight);

주변광을 설정한다. 행성자체에도 기본적으로 자체적으로 빛을 낸다.

■ 광원

CChildView::Init() 에서

glLightfv(GL_LIGHT0,GL_DIFFUSE,m_sourceLight);

glLightfv(GL_LIGHT0,GL_POSITION,m_lightPos);

glEnable(GL_LIGHT0);

광원을 태양의 위치에 두고 행성들이 마치 태양에서 빛을 받아 반사하는 듯한 효과를 주게 한다.

■ 텍스처링

CChildView::ReadTexture()

11개의 텍스처(태양, 수성...명왕성, 궤도선)를 생성하고 CBmp 클래스를 통해 비트맵 이미지를 읽어 텍스처를 생성한다.

CChildView::Draw() 에서

glBindTexture(GL_TEXTURE_2D, textureid[ORBITLINE]);

glBindTexture(GL_TEXTURE_2D, textureid[i]);

텍스처를 입힐때 그 행성에 해당하는 텍스처를 입혀야 한다.

■ SolarSystem 클래스

SolarSystem() : 모든 행성을 생성하고 초기화한다

virtual ~SolarSystem() : 행성을 삭제한다

void Slow() : 진행속도를 느리게 한다

void Fast() : 진행속도를 빠르게 한다

void Clock() : 1프레임에 해당하는 시간에 행성의 공전/자전을 수행한다

■ Planet 클래스

Planet(float,float,float,float) : 원에 가까운 궤도를 가진 행성을 위한 생성자

Planet(float,float,float,float,float,float) : 타원궤도를 가진 행성을 위한 생성자

float GetRotationAngle() : 현재 자전한 각도를 반환한다

float GetAngleY(float Angle) : 궤도선을 얻기위해 특정 각도에서의 y위치를 반환한다

float GetAngleX(float Angle) : 궤도선을 얻기위해 특정 각도에서의 x위치를 반환한다

float GetY() : 현재 y 위치를 반환한다

float GetX() : 현재 x 위치를 반환한다

float GetRadius() : 행성의 반지름을 반환한다

int GetYear() : 해당 행성의 공전을 1년으로 하는 행성력 년을 반환한다

( 테스트를 위한 MFC모델에서 쓰였음 )

void Run(int nCount) : nCount*10분동안의 공전과 자전을 처리한다

float radian(float dAngle) : 각도를 라디안값으로 바꿔준다

■ CBmp 클래스

bool LoadBitmap(char *filename) : 비트맵을 읽어 메모리에 할당한다

void FreeImage() : 할당된 메모리를 해제한다

■ CChildView 클래스

void Init() : 효과를 설정하고, 구형객체를 생성한다

void Draw() : 태양계 모델을 그린다

void ReadTexture() : 비트맵 텍스처를 읽는다

void OnPaint() : 윈도우 갱신시 Draw()를 호출하고, 더블버퍼링을 수행한다

BOOL OnEraseBkgnd(CDC* pDC) : InvalidateRect(NULL)을 설정하여도 화면이 깜빡거림을 막기위해 항상 FALSE로 설정한다

void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) : 키보드조작 처리

int OnCreate(LPCREATESTRUCT lpCreateStruct) : 윈도우 생성시 픽셀포맷을 얻고, DC를 오픈지엘과 연결하며, Init()를 호출, 타이머를 설정한다

void OnDestroy() : 타이머를 해제하고 RC를 삭제하고, DC의 사용을 해제한다.

void OnLButtonDown(UINT nFlags, CPoint point) : 각도조절 시작점 설정

void OnLButtonUp(UINT nFlags, CPoint point) : 거리조절 시작점 설정

void OnMouseMove(UINT nFlags, CPoint point) : 각도조절, 거리조절

void OnSize(UINT nType, int cx, int cy) : 윈도우 사이즈 변경시 뷰포트를 변경한다

void OnTimer(UINT nIDEvent) : 타임 이벤트 발생시 태양계에 1프레임을 진행한다

4. 결론

4.1 문제점 언급

■ 태양을 투명으로 처리하지 못함

투명으로 태양을 처리하여 그 안의 광원이 있도록 하려 했지만 구현하지 못해 조명이 없는 텍스처로 처리하였다

■ 보는시점의 각도 변경시 약간의 어색함이 존재

각도의 회전시 이전 보이는 각도에서 회전을 해야 하지만, 원래의 상태에서 회전을 함으로 생기는 어색함이 있다.

■ 배경의 텍스처를 입히지 못함

우주의 분위기에 맞게 별들의 텍스처를 입히지 못한 점

4.2 개선방향 제시

■ 보는시점의 각도 변경시 이전에 변경된 각도를 저장하여 그 위에 또 변경하는 방식으로 두 번째 문제점을 해결할 수 있다.

■ 텍스처가 커졌을때 느려지는 현상을 해결해야한다

5. 참고문헌(자료):

"OpenGL 프로그래밍", 우상수, 사이버출판사, 1998

"컴퓨터그래픽스 배움터", 최윤철.임순범.고견 공저, 생능출판사, 2003

http://www.solarne.com/

http://www.ultimategameprogramming.com/

http://liftoff.msfc.nasa.gov/academy/space/solarsystem/solarsystemjava.html

http://www.geocities.com/eagle_speaks/SolarSim/Appframe.html

http://www.sssim.com/en/product/studio/download.html

http://grace.chonnam.ac.kr/%7Emelchi/research/opengl/glEvalCoord.html

http://profs.sci.univr.it/~colombar/html_openGL_tutorial/en/index.html