math.h
Remarks
천문학 프로그램에서 주로 사용되는 상수와 함수들을 정의하고 있습니다.
Constants
|
상수 |
값 |
|
PI |
3.1415926535897932384626433832795 |
|
DOUBLE_PI |
6.2831853071795864769252867665590 |
|
HALF_PI |
1.5707963267948966192313216916398 |
Functions
|
함수 |
설명 |
|
double rad2deg(double x); |
radian을 degree로 변환 |
|
double deg2rad(double x); |
degree를 radian로 변환 |
|
double cbrt(double x); |
세제곱을 구함 |
|
double normalize(double x, double from, double to); |
x값을 from과 to 사이로 normalize함 |
Examples
변수 x를 -π/2~π/2 사이의 영역으로 맞추고 싶다면 다음과 같이 하면 됩니다.
normalize(x, -HALF_PI, HALF_PI);
time.h
Remarks
시간에 관련된 데이터 타입과 함수들을 정의하고 있습니다.
Types
typedef struct {int year,month,day,hour,minute,second;} TIME;
Functions
|
함수 |
설명 |
|
double jd(int year, int month, int day, int hour, int minute, int second); |
JD를 구함 |
|
void gregorian(double jd, TIME* t); |
그레고리력 날짜를 구함 |
|
double lct2ut(double lct, double dgmt); |
Local Civil Time을 Universal Time으로 바꿈 |
|
double ut2lct(double ut, double dgmt); |
Universal Time을 Local Civil Time으로 바꿈 |
|
double ut2gst(double ut); |
Universal Time을 Greenwich Sidreal Time으로 바꿈 |
|
double gst2ut(double gst); |
Greenwich Sidreal Time을 Universal Time으로 바꿈 |
|
double gst2lst(double gst, double lon); |
Greenwich Sidreal Time을 Local Sidreal Time으로 바꿈 |
|
double lst2gst(double lst, double lon); |
Local Sidreal Time을 Greenwich Sidreal Time으로 바꿈 |
Examples
2002년 1월 1일 0시 0분 0초의 율리우스 역일을 구하고 싶다면 다음과 같이 하면 됩니다.
now = jd(2002,1,1,0,0,0);
이 시간을 ut로 변환하고 싶다면(한국을 기준)
ut = lct2ut(now, 9);
이 시간을 gst로 변환하고 싶다면
gst = ut2gst(ut);
이 시간, 동경 127도에서의 지방항성시(local sidreal time, LST)를 구하고 싶다면
lst = gst2lst(gst, 127);
coord.h
Remarks
좌표계에 관한 함수들을 정의하고 있습니다.
Types
typedef union
{
struct {double r,lon,lat;} sphe;
struct {double x,y,z;} rect;
double element[3];
} VECTOR;
typedef struct
{
double element[3][3];
} MATRIX;
Functions
|
함수 |
설명 |
|
void equ2hor(VECTOR* v, double lst, double lat); |
적도좌표계를 지평좌표계로 변환 |
|
void hor2equ(VECTOR* v, double lst, double lat); |
지평좌표계를 적도좌표계로 변환 |
|
void equ2gal(VECTOR* v); |
지평좌표계를 은하좌표계로 변환 |
|
void gal2equ(VECTOR* v); |
은하좌표계를 적도좌표계로 변환 |
|
void equ2ecl(VECTOR* v, double jd); |
적도좌표계를 황도좌표계로 변환 |
|
void ecl2equ(VECTOR* v, double jd); |
황도좌표계를 적도좌표계로 변환 |
|
void _rect2sphe(VECTOR* v); |
내부에서 사용되는 함수이며 직교좌표계를 구면좌표계로 변환하는 행렬을 리턴 |
|
void _sphe2rect(VECTOR* v); |
내부에서 사용되는 함수이며 구면좌표계를 직교좌표계로 변환하는 행렬을 리턴 |
|
void _transform(VECTOR* v, MATRIX* m); |
내부에서 사용되는 함수이며 변환 행렬을 이용하여 벡터를 변환 |
|
void _equ2hor(MATRIX* m, double lst, double lat); |
내부에서 사용되는 함수이며 적도좌표계를 지평좌표계로 변환하는 행렬을 리턴 |
|
void _hor2equ(MATRIX* m, double lst, double lat); |
내부에서 사용되는 함수이며 지평좌표계를 적도좌표계로 변환하는 행렬을 리턴 |
|
void _equ2gal(MATRIX* m); |
내부에서 사용되는 함수이며 적도좌표계를 은하좌표계로 변환하는 행렬을 리턴 |
|
void _gal2equ(MATRIX* m); |
내부에서 사용되는 함수이며 은하좌표계를 적도좌표계로 변환하는 행렬을 리턴 |
|
void _equ2ecl(MATRIX* m, double jd); |
내부에서 사용되는 함수이며 적도좌표계를 황도좌표계로 변환하는 행렬을 리턴 |
|
void _ecl2equ(MATRIX* m, double jd); |
내부에서 사용되는 함수이며 황도좌표계를 적도좌표계로 변환하는 행렬을 리턴 |
Examples
일단 변환하고자 하는 좌표로 VECTOR를 만들어야 합니다.
VECTOR v; v.sphe.r = 1.0; // 별까지의 거리, 중요하지 않을시에는 아무값이나 세팅(여기서는 1.0을 사용) v.sphe.lat = 23.0; // 적위값 v.shpe.lon = 133.0; // 적경값
다음에 적당한 변환 함수를 호출하기만 하면 되죠.
equ2hor(&v,lst,lat);
이 함수들은 내부적으로 다음과 같은 단계를 거칩니다.
- _sphe2rect 함수를 이용해서 벡터를 직교좌표로 직접 변환(변환을 하기 위해서는 직교좌표계여야함)
- _equ2hor와 같은 함수를 이용해서 변환 matrix를 얻어온 후
- _transform 함수를 이용해서 변환 matrix와 벡터를 곱함
- _rect2sphe 함수를 이용해서 벡터를 다시 구면 좌표계로 변환
만일 많은 수의 별들에대해 변환을 수행하고자할 때 내부 사용함수들을 사용하여 직접 수동으로 변환할 수도있습니다. 이 방식은 좌표계 변환에 필요한 값들을(이 값을 구하는데 많은 cos, sin 함수들을 호출해야합니다, 즉 시간이 많이 걸린단 말이죠) 미리 행렬에 encoding해 두고 한번에 모두 변환하므로 빠릅니다. 이렇게하면 중복되는 작업을 모두 줄이고 정말 꼭 해야할 계산만 하게 되는 것이죠. Intel Celeron 500 MHz CPU에서 1000만개의 별들에 대해 equ2hor를 계산하는데 약 40%의 퍼포먼스 향상이 있었습니다.(High Level은 1.922초, Low Level은 1.392초)
Low Level 함수들을 사용하여 이 별의 현재 고도와 방위각을 알아보겠습니다. 미리 관측자의 위도(lat)와 지방 항성시(lst)는 계산되어있어야 합니다. 지방항성시를 구하기 위해서는 time.h에 정의되어있는 함수들을 사용하세요.
MATRIX m; _sphe2rect(&v); _equ2hor(&m,lst,lat); _transform(&v, &m); _rect2sphe(&v);
출력을 하려면 다음과 같이 하세요. rad2deg는 math.h에 정의되어있습니다.
printf("방위각 : %lf\n", rad2deg(v.sphe.lon));
printf("고도 : %lf\n", rad2deg(v.sphe.lat));