天文算法--分点和至点

本文给出二分点和二至点的大约时间的算法。参考《天文算法》。适用年份为-1000年~+3000年,精度在代码中给出。后续再补全高精度算法。

package cn.ancony.chinese_calendar;import lombok.AllArgsConstructor;
import lombok.Data;import static java.lang.Math.*;/*** 分点和至点* <p>* 分点和至点时刻是指:太阳的地心视黄经(含光行差和章动)为 90 的整位数时对应的时刻。* <p>* 大约时间的计算方法:(适用范围:-1000年~+3000年)* 1. 使用代码中jde0开头的方法计算对应的平分点或平至点,得到JDEo。* 2. 计算T,W,* T = (JDEo - 2451545.0)/36525* W = 35999°.373T - 2°.47* Δλ= 1 + 0.0334 cos W + 0.0007 cos 2W* 3. 使用T和sTable计算S。* S = Σ(A * cos(B + C * T))* 4. 要计算的分点或至点时刻(儒略历书时,即力学时)表达为:* JDE = JDEo + 0.00001*S/Δλ* <p>* 这种方法,在公元1951——2050的精度如下:* |-------|------------------|------------------|------|* |       |误差小于20秒的年份个数|误差小于40秒的年份个数|最大误差|* |-------|------------------|------------------|------|* | 3月分点|       76         |        97        |  51  |* | 6月分点|       80         |       100        |  39  |* | 9月分点|       78         |        99        |  44  |* |12月分点|       68         |        99        |  41  |* |-------|------------------|------------------|------|*/
public class EquinoxAndSolstice {//计算大致时间的公式的使用范围。单位:年private static final int low = -1000, mid = 1000, up = 3000;/*** 计算某一个年的分点和至点** @param year 年份。范围:-1000 ~ +3000。* @return 返回四个分点/至点。分别为3月分点,6月至点,9月分点,12月至点。单位:JDE*/public static double[] jde(int year) {checkYear(year);return year > mid ?new double[]{jde(jde010(year)), jde(jde011(year)), jde(jde012(year)), jde(jde013(year))} :new double[]{jde(jde000(year)), jde(jde001(year)), jde(jde002(year)), jde(jde003(year))};}//返回春分点public static double springEquinoxJde(int year) {checkYear(year);return year > mid ? jde(jde010(year)) : jde(jde000(year));}//返回夏至点public static double summerSolsticeJde(int year) {checkYear(year);return year > mid ? jde(jde011(year)) : jde(jde001(year));}//返回秋分点public static double autumnalEquinoxJde(int year) {checkYear(year);return year > mid ? jde(jde012(year)) : jde(jde002(year));}//返回冬至点public static double winterSolsticeJde(int year) {checkYear(year);return year > mid ? jde(jde013(year)) : jde(jde003(year));}private static void checkYear(int year) {if (year < low || year > up)throw new RuntimeException(String.format("计算范围是:%s ~ %s", low, up));}/*** 传入JDEo,得到分点或至点时刻(JDE)** @param jde0 JDEo,分或至的时刻* @return JDE(儒略历书时, 即力学时)*/private static double jde(double jde0) {double t = (jde0 - 2451545.0) / 36525, w = 35999.373 * t - 2.47,deltaLambda = 1 + 0.0334 * cos(toRadians(w)) + 0.0007 * cos(toRadians(2 * w));//计算Sdouble s = 0;for (int i = 0; i < sTable.length; i += 3) {double a = sTable[i], b = sTable[i + 1], c = sTable[i + 2];s += a * cos(toRadians(b + c * t));}return jde0 + 0.00001 * s / deltaLambda;}// ==================== -1000~+1000 JDE0的计算 ====================private static double year0(int year) {return (double) year / 1000;}//-1000~+1000 3月平分点时刻JDEoprivate static double jde000(int year) {return c0(year0(year), new byte[]{1, 1, 1, 1, 0},new double[]{1721139.29189, 365242.13740, 0.06134, 0.00111, 0.00071});}//-1000~+1000 6月平至点时刻JDEoprivate static double jde001(int year) {return c0(year0(year), new byte[]{1, 1, 0, 1, 1},new double[]{1721233.25401, 365241.72562, 0.05323, 0.00907, 0.00025});}//-1000~+1000 9月平分点时刻JDEoprivate static double jde002(int year) {return c0(year0(year), new byte[]{1, 1, 0, 0, 1},new double[]{1721325.70455, 365242.49558, 0.11677, 0.00297, 0.00074});}//-1000~+1000 12月平至点时刻JDEoprivate static double jde003(int year) {return c0(year0(year), new byte[]{1, 1, 0, 0, 0},new double[]{1721414.39987, 365242.88257, 0.00769, 0.00933, 0.00006});}// ==================== +1000~+3000 JDEo的计算 ====================private static double year1(int year) {return (double) (year - 2000) / 1000;}//+1000~+3000 3月平分点时刻JDEoprivate static double jde010(int year) {return c0(year1(year), new byte[]{1, 1, 1, 0, 0},new double[]{2451623.80984, 365242.37404, 0.05169, 0.00411, 0.00057});}//+1000~+3000 6月平至点时刻JDEoprivate static double jde011(int year) {return c0(year1(year), new byte[]{1, 1, 1, 1, 0},new double[]{2451716.56767, 365241.62603, 0.00325, 0.00888, 0.00030});}//+1000~+3000 9月平分点时刻JDEoprivate static double jde012(int year) {return c0(year1(year), new byte[]{1, 1, 0, 1, 1},new double[]{2451810.21715, 365242.01767, 0.11575, 0.00337, 0.00078});}//+1000~+3000 12月平至点时刻JDEoprivate static double jde013(int year) {return c0(year1(year), new byte[]{1, 1, 0, 0, 1},new double[]{2451900.05952, 365242.74049, 0.06223, 0.00823, 0.00032});}/*** 计算形如 ratio1 * y^0 + ratio2 * y^1 + ratio3 * y^2 + ... + ratioN * y^(N-1)方程的结果** @param y        y* @param positive 是否为正号。只能取1(正号)和0(负号).* @param ratios   系数* @return 结果*/private static double c0(double y, byte[] positive, double[] ratios) {int len1 = ratios.length, len2 = positive.length;if (len1 != len2) throw new RuntimeException("数组大小必须等长");double[] yes = new double[len1];yes[0] = 1;double ans = ratios[0];for (int i = 1; i < len1; i++) {yes[i] = y * yes[i - 1];double temp = ratios[i] * yes[i];if (positive[i] == 1) ans += temp;else ans -= temp;}return ans;}/*** 3个一组,分别表示A,B,C。共24组。用来计算S。B和C的单位是"度"。(对应天文算法中的表26.C)* S = Σ(A * cos(B + C * T))*/public static final double[] sTable = {485, 324.96, 1934.136, 203, 337.23, 32964.467, 199, 342.08, 20.186, 182, 27.85, 445267.112,156, 73.14, 45036.886, 136, 171.52, 22518.443, 77, 222.54, 65928.934, 74, 296.72, 3034.906,70, 243.58, 9037.513, 58, 119.81, 33718.147, 52, 297.17, 150.678, 50, 21.02, 2281.226,45, 247.54, 29929.562, 44, 325.15, 31555.956, 29, 60.93, 4443.417, 18, 155.12, 67555.328,17, 288.79, 4562.452, 16, 198.04, 62894.029, 14, 199.76, 31436.921, 12, 95.39, 14577.848,12, 287.11, 31931.756, 12, 320.81, 34777.259, 9, 227.73, 1222.114, 8, 15.45, 16859.074};}

以下是测试类:

package cn.ancony.javafx.chinese_calendar;import cn.ancony.chinese_calendar.JulianDay;
import cn.ancony.chinese_calendar.LevelConvert;
import cn.ancony.chinese_calendar.YearMonthDay;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;import static cn.ancony.chinese_calendar.EquinoxAndSolstice.*;
import static org.junit.jupiter.api.Assertions.assertTrue;public class TestEquinoxAndSolstice {/*** 测试数据为1991-2000年二分二至时刻,VSOP87理论计算,力学时。精度:接近于秒。* 参数含义依次为:年份,3月分点,6月至点,9月分点,12月分点。* 分点和至点均由5个参数组成,前两个表示月份和日期,后三个表示时分秒。*/@ParameterizedTest@CsvSource({"1991,  3,21,  3, 2,54,  6,21, 21,19,46,  9,23, 12,49, 4,  12,22,  8,54,38","1992,  3,20,  8,49, 2,  6,21,  3,15, 8,  9,22, 18,43,46,  12,21, 14,44,14","1993,  3,20, 14,41,38,  6,21,  9, 0,44,  9,23,  0,23,29,  12,21, 20,26,49","1994,  3,20, 20,29, 1,  6,21, 14,48,33,  9,23, 12,14, 1,  12,22,  8,17,50","1995,  3,21,  2,15,27,  6,21, 20,35,24,  9,23, 12,14, 1,  12,22,  8,17,50","1996,  3,20,  8, 4, 7,  6,21,  2,24,46,  9,22, 18, 1, 8,  12,21, 14, 6,56","1997,  3,20, 13,55,42,  6,21,  8,20,59,  9,22, 23,56,49,  12,21, 20, 8, 5","1998,  3,20, 19,55,42,  6,21, 14, 3,38,  9,23,  5,38,15,  12,22,  1,57,31","1999,  3,21,  1,46,53,  6,21, 19,50,11,  9,23, 11,32,34,  12,22,  7,44,52","2000,  3,20,  7,36,19,  6,21,  1,48,46,  9,22, 17,28,40,  12,21, 13,38,30"})public void test1(int year,int mn1, int d1, int h1, int m1, int s1,int mn2, int d2, int h2, int m2, int s2,int mn3, int d3, int h3, int m3, int s3,int mn4, int d4, int h4, int m4, int s4) {double[] jde = jde(year);assertTrue(check(year, mn1, d1, h1, m1, s1, jde[0], 0));assertTrue(check(year, mn2, d2, h2, m2, s2, jde[1], 1));assertTrue(check(year, mn3, d3, h3, m3, s3, jde[2], 2));assertTrue(check(year, mn4, d4, h4, m4, s4, jde[3], 3));}//大致时间的最大误差,单位:秒private static final int[] MAX_ERROR = {51, 39, 44, 41};private static final int checkSupportedMinYear = 1951, checkSupportedMaxYear = 2050;private static boolean check(int year, int month, int date, int hour, int minute, int second,double julianActual, int no) {if (year < checkSupportedMinYear || year > checkSupportedMaxYear)throw new RuntimeException(String.format("仅支持检查%d年~%d年之间的误差。",checkSupportedMinYear, checkSupportedMaxYear));double intervalDays = JulianDay.intervalDays(YearMonthDay.of(year, month, date, hour, minute, second),JulianDay.convert(julianActual));return (int) (intervalDays * LevelConvert.DayHourMinuteSecond.getProduct()) < MAX_ERROR[no];}/*** 一些历元的四个天文季节的时间长度,单位:天* 数据格式:年份,春,夏,秋,冬*/@ParameterizedTest@CsvSource({"-4000, 93.54, 89.18, 89.08, 93.43","-3500, 93.82, 89.53, 88.82, 93.07","-3000, 94.04, 89.92, 88.62, 92.67","-2500, 94.19, 90.33, 88.48, 92.24","-2000, 94.28, 90.76, 88.40, 91.81","-1500, 94.30, 91.20, 88.38, 91.37","-1000, 94.25, 91.63, 88.42, 90.94"," -500, 94.14, 92.05, 88.53, 90.52","    0, 93.96, 92.45, 88.70, 90.14","  500, 93.73, 92.82, 88.92, 89.78"," 1000, 93.44, 93.15, 89.18, 89.47"," 1500, 93.12, 93.42, 89.50, 89.20"," 2000, 92.76, 93.65, 89.84, 88.99"," 2500, 92.37, 93.81, 90.22, 88.84"," 3000, 91.97, 93.92, 90.61, 88.74"," 3500, 91,57, 93.96, 91.01, 88.71"," 4000, 91.17, 93.93, 91.40, 88.73"," 4500, 90.79, 93.84, 91.79, 88.82"," 5000, 90.44, 93.70, 92.15, 88.96"," 5500, 90.11, 93.50, 92.49, 89.14"," 6000, 89.82, 93.25, 92.79, 89.38"," 6500, 89.58, 92.97, 93.04, 89.65"})public void testLength(int year, double spring, double summer, double autumn, double winter) {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

inno setup 卸载程序 删除整个安装目录

业务场景&#xff1a;有次客户反馈说&#xff0c;卸载应用程序没有卸载干净&#xff0c;安装目录下残留很多文件&#xff0c;特别是一些配置文件和数据库文件&#xff0c;涉及到一些数据安全机密。卸载程序应该把安装目录都要清除。操作如下&#xff1a; 卸载应用程序&#xf…

利用Redis实现简单的短信登录

在现代应用中&#xff0c;短信登录是一种常见的用户认证方式。它提供了一种便捷的登录方式&#xff0c;同时也增加了账户的安全性。在本文中&#xff0c;我们将介绍如何使用 Redis 实现短信登录的功能&#xff0c;并提供相应的 Java 实现层代码。 1、短信验证码的生成与存储当用…

Java自带的线程池及调用、ThreadPoolExecutor类(线程池的7大参数)、任务队列及底层原理

day32 线程池 引入 一个线程完成一项任务所需时间为&#xff1a; 创建线程时间 - Time1线程中执行任务的时间 - Time2销毁线程时间 - Time3 注意&#xff1a;优化在Time1&#xff0c;Time3(创建销毁线程费时间) 为什么需要线程池 线程池技术正是关注如何缩短或调整Time1和Tim…

Facebook轮播广告是什么?投放过程中有哪些需要注意的吗?

轮播广告是Facebook广告形式中的一种&#xff0c;可以把3—5个广告合并到一个可滚动的广告单元中。轮播广告会出现在新鲜事即News Feed中&#xff0c;是独立站卖家常用的一种广告形式 为什么选择轮播广告&#xff1f; 转化率更高&#xff1a;相较于单图广告&#xff0c;轮播广…

基于单片机输出PWM 波控制的音乐喷泉系统设计

摘 要:随着经济、文化的发展,音乐喷泉作为一种观赏性较高的艺术水景,逐渐出现在全国城市中。但在音乐与喷泉喷射配合过程中,并没有实现二者同步,存在时滞。为此,设计了以STC89C52单片机为核心的小型音乐喷泉控制系统。音乐信号经放大通过A/D转换器处理,送入…

Springboot+vue的高校科研信息管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的高校科研信息管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#x…

计算机网络(第八版)-第1章课后习题参考答案

计算机网络(第八版)-第1章课后习题参考答案 本文是对自己之前文章的格式化&#xff1a;https://blog.csdn.net/qq_46396470/article/details/132788972?spm1001.2014.3001.5502 T1-01 计算机网络向用户可以提供哪些服务&#xff1f; 连通性和共享 &#xff0c;例如音频&…

修改docker容器日志大小

docker-compose.yaml logging:options:max-size: "10m"docker run docker run -d \--name example-container \--log-opt max-size10m \--log-opt max-file3 \nginx:latestdocker daemon全局配置 /etc/docker/daemon.json 参考文档&#xff1a;https://docs.docker…

【Node.JS】koa

文章目录 概述koa和express对比koa下载安装使用1.创建koa项目文件目录2. 创建koa服务3. 添加路由 koa-router4. 数据库服务 mongodb5. 添加请求参数json处理 koa-bodyparser6. 用户接口举例7.引入koa一些常用插件8.用户登录验证 koa-jwt9.webpack生产打包 来源 概述 Koa 是一个…

A fatal error occurred: MD5 of file does not match data in flash!问题解决

采用的芯片是ESP32-S3-WROOM&#xff0c;16MB FLASH 开发环境是Arduino&#xff0c;烧录到100%后直接报错。 以为是Arduino的问题&#xff0c;用esp-idf开发的程序&#xff0c; 烧录的过程中&#xff0c;也是直接报错如下&#xff1a; esptool.py v4.7.0 Serial port /dev/…

k8s下搭建redis集群

记录一下近期实现的在k8s上搭建redis集群的过程 1、新建存储类 主要是为了和其它服务的存储类区分一下 redis-beta-storage 2、编写configMap redis启动时从configMap中读取配置 bind&#xff1a;默认的127.0.0.1可能会导致其它ip地址无法远程访问&#xff0c;因此修改为0.0…

战略定位--选择什么赛道。成为什么样的企业。

2、原则&#xff1a;选择细分赛道&#xff0c;做头部客户 &#xff08;1&#xff09;刘伯承&#xff1a;打仗&#xff1a;五行要定、五行不定输的干净、定阵地、了解我情、了解敌情、目标清楚、时间清楚 &#xff08;2&#xff09;中小企业不在规模在 &#xff08;3&#xff09…

揭秘情绪识别:如何让AI读懂你的心声?

最近我在研究大语言模型&#xff0c;想用它来给样本打分。 起初&#xff0c;我尝试让模型用1到5分来评分&#xff0c;但它总是极端地给出最低分或最高分&#xff0c;评分缺乏中间地带。 于是我换了个方法&#xff0c;不再用数字&#xff0c;而是用描述性的词语&#xff0c;比…

【Golang星辰图】加速开发的利器:揭秘Go语言的高效工具集

工具库&#xff1a;提升Go语言开发效率的利器 前言 在现代软件开发中&#xff0c;拥有高效、灵活的工具库是开发人员提高工作效率和简化开发流程的关键。本文将介绍几个优秀的工具库&#xff0c;它们为Go语言开发提供了强大的功能和便捷的工具&#xff0c;帮助开发人员更轻松…

农村集中式生活污水分质处理及循环利用技术指南

立项单位&#xff1a;生态环境部土壤与农业农村生态环境监管技术中心、山东文远环保科技股份有限公司、北京易境创联环保有限公司、中国环境科学研究院、广东省环境科学研究院、中铁第五勘察设计院集团有限公司、中华环保联合会水环境治理专业委员会 本文件规定了集中式村镇生活…

常用的几个ChatGPT网站,国内可用!

&#x1f310; 链接&#xff1a; ChatAI &#x1f3f7;️ 标签&#xff1a; GPT-4 免费体验 付费选项 &#x1f4dd; 简介&#xff1a;ChatAI 是一个功能强大的平台&#xff0c;提供GPT-4&#xff0c;不限使用次数&#xff0c;不限Token。用户可以选择包月或是更灵活的按次付…

Discourse 最多允许有几个分类级别

和 DISCUZ 不同&#xff0c;DISCUZ 可以允许分类下面还有分类&#xff0c;再继续分类这种嵌套式分类。 Discourse 最多只允许有 2 个分类。 如果你在已有的分类下再继续分类的话&#xff0c;系统会提示错误&#xff1a; 意思就是子分类不能再分子分类。 Discourse 尽量采取了…

数据结构(六)——图

六、图 6.1 图的基本概念 图的定义 图&#xff1a;图G由顶点集V和边集E组成&#xff0c;记为G (V, E)&#xff0c;其中V(G)表示图G中顶点的有限非空集&#xff1b;E(G) 表示图G中顶点之间的关系&#xff08;边&#xff09;集合。若V {v1, v2, … , vn}&#xff0c;则用|V|…

计算机基础系列 —— 虚拟机代码翻译器(1)

“Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.” ―Linus Torvalds 文中提到的所有实现都可以参考&#xff1a;nand2tetris_sol&#xff0c;但是最好还是自己学习课程实现一…

Linux基础 超详细!!!

一、Linux基础命令 &#xff08;一&#xff09;Linux的目录结构 1、盘符 Linux中无盘符的概念&#xff0c;只有一个根目录 “/” 也就是只有一棵树) 而windows里面有多棵树&#xff0c;每个盘符都是一棵树的根 在Linux系统中&#xff0c;路径之间的层级关系&#xff0c;使用…