Java中计算天体视差改正的数学错误
我正在实施这本书的计算。到目前为止,我的计算结果与书中的示例计算结果完全相同 然而,在第39条“计算视差修正”中,我遇到了一个我无法理解的差异 手头的任务描述如下:Java中计算天体视差改正的数学错误,java,math,astronomy,Java,Math,Astronomy,我正在实施这本书的计算。到目前为止,我的计算结果与书中的示例计算结果完全相同 然而,在第39条“计算视差修正”中,我遇到了一个我无法理解的差异 手头的任务描述如下: static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) { double Hd = 15d * raha(body.α, zdt, o
static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
double Hd = 15d * raha(body.α, zdt, observer.λ);
step("α", body.α);
step("δ", body.δ);
step("φ", observer.φ);
step("λ", observer.λ);
step("h", observer.h);
step("H", Hd);
double H = toRadians(Hd);
Parallax ρ = parallax(observer.φ, observer.h);
step("P", P);
P = toRadians(P);
double δ = toRadians(body.δ);
double r = 1d / sin(P);
step("r", r);
double ρsinφ = ρ.sin;
double ρcosφ = ρ.cos;
step("ρcosφ'",ρcosφ);
step("ρsinφ'",ρsinφ);
double Δ = atan((ρcosφ * sin(H)) / ((r * cos(δ)) - (ρcosφ * cos(H))));
step("Δ", toDegrees(Δ));
H += Δ;
step("H'", toDegrees(H));
Δ = toDegrees(Δ);
double α$ = body.α - (Δ / 15d);
step("α'", α$);
double divident = (r * sin(δ)) - ρsinφ;
double divisor = ( r * cos(δ) * cos(H) ) - ρcosφ;
double δ$ = atan(cos(H) * (divident / divisor));
δ$ = toDegrees(δ$);
step("δ'", δ$);
return new EquatorialCoordinate(α$, δ$);
}
举个例子,让我们计算一下26日月球的视赤经和赤纬
1979年2月16时45米UT,从海拔60米的位置观测,经度为100°W,纬度为50°N。地心坐标为α=22h 35m 19s,δ=−7°41′13′,月球赤道水平视差为1°01′09′
本书对计算顺序的描述如下:
然而,我第7步的结果是−31.993415,但书上说−31,994415。如果我用计算器计算第7步的数学,结果是−31.993415,所以我的结果似乎是对的,而这本书是错的
我可以接受,但第10步也有不同。我的结果是-8570634,书本的结果是-8.538165,差别很大。我一遍又一遍地阅读步骤10,看看我的代码中是否有错误,但我没有看到
到目前为止,我的计算和书本上的计算完全一样,我被卡住了。我是做错了什么(首选),还是这本书出错了(希望不会再有了……)
此函数的Java代码如下所示:
static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
double Hd = 15d * raha(body.α, zdt, observer.λ);
step("α", body.α);
step("δ", body.δ);
step("φ", observer.φ);
step("λ", observer.λ);
step("h", observer.h);
step("H", Hd);
double H = toRadians(Hd);
Parallax ρ = parallax(observer.φ, observer.h);
step("P", P);
P = toRadians(P);
double δ = toRadians(body.δ);
double r = 1d / sin(P);
step("r", r);
double ρsinφ = ρ.sin;
double ρcosφ = ρ.cos;
step("ρcosφ'",ρcosφ);
step("ρsinφ'",ρsinφ);
double Δ = atan((ρcosφ * sin(H)) / ((r * cos(δ)) - (ρcosφ * cos(H))));
step("Δ", toDegrees(Δ));
H += Δ;
step("H'", toDegrees(H));
Δ = toDegrees(Δ);
double α$ = body.α - (Δ / 15d);
step("α'", α$);
double divident = (r * sin(δ)) - ρsinφ;
double divisor = ( r * cos(δ) * cos(H) ) - ρcosφ;
double δ$ = atan(cos(H) * (divident / divisor));
δ$ = toDegrees(δ$);
step("δ'", δ$);
return new EquatorialCoordinate(α$, δ$);
}
“step”函数执行一个简单的格式化printf。该程序的输出为:
- α22.588611
- δ-7.686944
- φ50.000000
- λ-100.000000
- h 60.000000
- H-31.642500
- 第1.019167页
- r 56.221228
- ρcosφ'0.644060
- ρsinφ'0.762422
- Δ-0.350915
- H'-31.993414
- α'22.612005
- δ'-8.570634
H += Δ;
这会改变H的值
然后你写
double δ$ = atan(cos(H) * (divident / divisor));
当它应该使用旧值时,它使用了新版本的H。多亏了@svasa,我发现步骤10的除数应该包含H,而不是H'。 正确的代码是:
static EquatorialCoordinate parallax(EquatorialCoordinate body, ObserverLocation observer, ZonedDateTime zdt, double P) {
double H = toRadians(15d * raha(body.α, zdt, observer.λ));
P = toRadians(P);
Parallax ρ = parallax(observer.φ, observer.h);
double δ = toRadians(body.δ);
double r = 1d / sin(P);
double Δ = atan((ρ.cosφ * sin(H)) / ((r * cos(δ)) - (ρ.cosφ * cos(H))));
double H$ = H + Δ;
double α$ = body.α - (toDegrees(Δ) / 15d);
double δ$ = toDegrees(atan(cos(H$) * ((r * sin(δ) - ρ.sinφ) / (r * cos(δ) * cos(H) - ρ.cosφ))));
return new EquatorialCoordinate(α$, δ$);
}
假设您的计算是正确的,这很可能是由于
double
计算中的重复错误造成的。试着用一个BigDecimal
。我有个问题。您是如何在java代码中键入这些符号的?我附议:这里有一些繁重的计算,使用浮点数会导致精度错误。使用BigDecimal
应该会有帮助。@svasa Java编译器接受unicode,因为这些“符号”是希腊字符,所以它们是有效的变量名。你可以用它写一些讨厌的东西(我记得有人在这里用阿拉伯语写代码,在ltr和rtl之间切换)-你能做到这一点并不意味着你应该做到;)@Thomas那么你是如何在代码中输入这些符号的,你使用一些特殊的键盘吗?或者写一些像U+10400的东西?