内存受限系统如何实现日出日落算法

         如题,前段时间应对客户需求,在芯片上增加一些功能,发现芯片空间即满,为了能够把新功能加进去,进行了代码的重新优化,发现之前的天文时钟代码占用空间比较大,所以从这个入手,天文时钟的计算方法如下,标准库函数库编译代码13KB左右,经过分析得出,标准的数学库,在处理三角函数的时候耗费空间很大,在经过对其中三角函数改成查表法后,空间骤降到3KB左右,节约了10K空间,为后面新功能的增加创造了条件,提供一个思路给有类似需要的人。注:更改后的算法经测试验证无误,可以在项目上使用。

 

/*

 * Get the days to J2000

 * h is UT in decimal hours

 * FNday only works between 1901 to 2099 - see Meeus chapter 7

 */

 

static double FNday(int y, int m, int d, float h)

{

        long int luku = -7 * (y + (m + 9) / 12) / 4 + 275 * m / 9 + d;

        luku += (long int) y *367;

        return (double) luku - 730531.5 + h / 24.0;

}

 

static double FNrange(double x)

{

        double b = 0.5 * x / M_PI;

        double a = 2.0 * M_PI * (b - (long) (b));

        if (a < 0)

                a = 2.0 * M_PI + a;

        return a;

}

 

/* Calculating the hourangle */

static double f0(double lat, double declin)

{

        double fo, dfo;

 

        dfo = RADS * (0.5 * SUNDIA + AIRREFR);

        if (lat < 0.0)

                dfo = -dfo;

        fo = get_tan(declin + dfo) * get_tan(lat * RADS);

        if (fo > 0.99999)

                fo = 1.0;

        return get_asin(fo) + M_PI / 2.0;

};

 

/* Calculating the hourangle for twilight times */

static double f1(double lat, double declin)

{

        double fi, df1;

 

        df1 = RADS * 6.0;

        if (lat < 0.0)

                df1 = -df1;

        fi = get_tan(declin + df1) * get_tan(lat * RADS);

        if (fi > 0.99999)

                fi = 1.0;

        return get_asin(fi) + M_PI / 2.0;

}

 

void sun(sunsetrise *ssr, int year, int month, int day, int tzone, double latit, double longit)

{

        double L, g;

        double d, lambda;

        double obliq, LL, equation, ha, hb;

        double settm, riset;

        double daylen;

 

        d = FNday(year, month, day, 12);

 

        /* mean longitude of the Sun */

        L = FNrange(280.461 * RADS + .9856474 * RADS * d);

 

        /* mean anomaly of the Sun */

        g = FNrange(357.528 * RADS + .9856003 * RADS * d);

 

        /* Ecliptic longitude of the Sun */

        lambda = FNrange(L + 1.915 * RADS * get_sin(g) + .02 * RADS * get_sin(2 * g));

 

        /* Obliquity of the ecliptic */

 

        obliq = 23.439 * RADS - .0000004 * RADS * d;

 

        /* Find the RA and DEC of the Sun */

        /* Find the Equation of Time in minutes */

        /* Correction suggested by David Smith */

        LL = L - get_atan2(get_cos(obliq) * get_sin(lambda), get_cos(lambda));

        if (L < M_PI)

                LL += 2.0 * M_PI;

        equation = 1440.0 * (1.0 - LL / M_PI / 2.0);

        ha = f0(latit, get_asin(get_sin(obliq) * get_sin(lambda)));

        hb = f1(latit, get_asin(get_sin(obliq) * get_sin(lambda)));

        /* Conversion of angle to hours and minutes */

        daylen = DEGS * ha / 7.5;

        if (daylen < 0.0001)

                daylen = 0.0;

        /* arctic winter */

        riset = 12.0 - 12.0 * ha / M_PI + (double)tzone - longit / 15.0 + equation / 60.0;

        settm = 12.0 + 12.0 * ha / M_PI + (double)tzone - longit / 15.0 + equation / 60.0;

 

        if (riset > 24.0)

                riset -= 24.0;

        if (settm > 24.0)

                settm -= 24.0;

 

        ssr->sunrise_h = (int)riset;

        ssr->sunrise_m = (int)((riset - ssr->sunrise_h) * 60);

        ssr->sunset_h = (int)settm;

        ssr->sunset_m = (int)((settm - ssr->sunset_h) * 60);

        ssr->daylen_h = (int)daylen;

        ssr->daylen_m = (int)((daylen - ssr->daylen_h) * 60);

 

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值