728x90
반응형

일출 일몰 시간을 알기 위해 검색 하던중 다음 사이트에서 자료를 보고 얻어왔다.

현재 테스트 중인데 문제점은 찾아야 하고 사용할수 있도록 수정해야함.

https://blog.naver.com/hy5236kr/140185719136

 

GPS 좌표와 Local Time을 이용한 일출/일몰시간 계산

먼저 소개했던 태양의 고도를 계산하는 알고리즘보다 더 정확한 결과를 얻어냈습니다. 물론 인터넷에서 찾...

blog.naver.com

 

위 사이트에서 복 붙이 안돼서 이곳에 남김.

 

//#include "stdafx"

#include <iostream>
#include <math.h>
#include <time.h>
using namespace std;
#define PHI 3.14159265f
#define TWO_PHI 6.28318530f //2*PHI
#define SUN_DIAMETER 0.53f //Sunradius degrees
#define AIR_REF (34.0f/60.0f) //athmospheric refraction degrees (지구대기 굴절각)

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;

typedef struct _DAYLIGHT_STRUCT_
{
uint8_t sunRise_hour;
uint8_t sunRise_minute;
uint8_t sunSet_hour;
uint8_t sunSet_minute;
}DAYLIGHT;

// Get the days to J2000
// h is UT in decimal hours
// getJulianDay only works between 1901 to 2099 - see Meeus chapter 7
// 이 함수는 J2000 1월 1일 12시 DT를 기준으로 날수(Day Number)를 구합니다. (Meeus의 책 챕터 7을 참고하세요)
// 입력값은 년,월,일,시간(실수값)입니다.
double getJulianDay(int year, int month, int day)
{
double temp = -7.0f * ((double)year + ((double)month + 9.0f) / 12.0f) / 4.0f + 275.0f * (double)month / 9.0f + (double)day;

// type casting necessary on PC DOS and TClite to avoid overflow
temp += (double)(year * 367);
return (temp - 730531.5f + 12.0f / 24.0f);
};

// the function below returns an angle in the range
// 0 to 2 * pi
//
// 들어온 값을 항상 0~2pi 값안으로 normalize 시킵니다.

double getRangeRadian(double x)
{
double b = x / TWO_PHI;
double a = TWO_PHI * (b - (long)(b));

if (a < 0) a = TWO_PHI + a;
return a;
};

// Calculating the hourangle
// 시간각을 계산합니다.
// lat : 위도 decli : 적위
double getHourAngle(double lat, double declin)
{
double fo, dfo;

// Correction : different sign at S HS
dfo = PHI / 180.0 * (0.5 * SUN_DIAMETER + AIR_REF);

if (lat < 0.0) dfo = -dfo;

fo = tan(declin + dfo) * tan(lat * PHI / 180.0);

if (fo > 0.99999) fo = 1.0; // to avoid overflow //

fo = asin(fo) + PHI / 2.0;

return fo;
};

// Find the ecliptic longitude of the Sun
// 태양의 황경을 구합니다.
double getSunLongitude(double days, double* Longitude)
{
double g;

// mean longitude of the Sun (태양의 평균 황경)
*Longitude = getRangeRadian(280.461 * PHI / 180.0 + .9856474 * PHI / 180.0 * days);

// mean anomaly of the Sun (태양의 평균근접이각)
g = getRangeRadian(357.528 * PHI / 180.0 + .9856003 * PHI / 180.0 * days);

// Ecliptic longitude of the Sun (태양의 황경계산)
return getRangeRadian(*Longitude + 1.915 * PHI / 180.0 * sin(g) + .02 * PHI / 180.0 * sin(2 * g));
};

static void convertDtime2Rtime(double dHour, unsigned char* hour, unsigned char* minute)
{
*hour = (uint8_t)dHour;
*minute = (uint8_t)((dHour - (double)*hour) * 60);
}

// 메인함수
int main(void)
{
int year, month, day;
double latitude, longitude;
double tzone;

double meanLongitude;
double lambda, obliq;
double alpha, delta;

double LL, days;
double equation, ha, sunRiseTime, sunSetTime;

DAYLIGHT sunTime;
uint16_t dSunRiseT = 0, dSunSetT = 0, dNowT = 0;

uint8_t hour, minute;

// 관측장소의 경도(단위 degree), 위도(단위 degree), 타임존(단위시간) 값을 입력받습니다.
//year = 2013;
//month = 3;
//day = 28;
year = 2024;
month = 6;
day = 11;

//latitude = 37.4681f; //한국내 임의 위치의 위도 입력
//longitude = 127.0282f; //한국내 임의 위치의 경도 입력
latitude = 35.0518f; //한국내 임의 위치의 위도 입력
longitude = 129.0221f; //한국내 임의 위치의 경도 입력
tzone = 9.0f; //한국은 Time Zone이 +9임

days = getJulianDay(year, month, day);

// 태양의 황경
lambda = getSunLongitude(days, &meanLongitude);
// Obliquity of the ecliptic (s황도기울기 계산)
obliq = 23.439 * PHI / 180.0 - .0000004 * PHI / 180.0 * days;

// Find the RA and DEC of the Sun (태양의 적격, 적위 계산)
alpha = atan2(cos(obliq) * sin(lambda), cos(lambda)); //태양의 적경
delta = asin(sin(obliq) * sin(lambda)); //태양의 적위

// Find the Equation of Time
// in minutes
// Correction suggested by David Smith
// 균시차 계산
LL = meanLongitude - alpha;

if (meanLongitude < PHI) LL += TWO_PHI;

equation = 1440.0 * (1.0 - LL / TWO_PHI);
ha = getHourAngle(latitude, delta);

sunRiseTime = 12.0 - 12.0 * ha / PHI + tzone - longitude / 15.0 + equation / 60.0;
sunSetTime = 12.0 + 12.0 * ha / PHI + tzone - longitude / 15.0 + equation / 60.0;

if (sunRiseTime > 24.0) sunRiseTime -= 24.0;
if (sunSetTime > 24.0) sunSetTime -= 24.0;

convertDtime2Rtime(sunRiseTime, &sunTime.sunRise_hour, &sunTime.sunRise_minute);
convertDtime2Rtime(sunSetTime, &sunTime.sunSet_hour, &sunTime.sunSet_minute);

hour = 18; minute = 48; //임의의 Local Time을 설정하여 테스트

cout << "Now Time : " << (int)hour << ':' << (int)minute << '\n';
cout << "Sunrise : " << (int)sunTime.sunRise_hour << ':' << (int)sunTime.sunRise_minute << '\n';
cout << "Sunset : " << (int)sunTime.sunSet_hour << ':' << (int)sunTime.sunSet_minute << '\n';

if (dNowT <= dSunRiseT || dNowT >= dSunSetT)
{
cout << "Night\n";
}
else
{
cout << "Day\n";
}
return 0;
}

아래는 프로제트 파일 첨부함.

GPS_POSITION.zip
19.82MB

728x90
반응형

+ Recent posts