From be6a08c0bc3cb312702fa67e40006320b57ba1aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6rber?= Date: Mon, 10 Apr 2023 14:56:27 +0200 Subject: [PATCH] Fix Moon parallactic angle calculation --- src/doc/docs/migration.md | 3 +++ .../shredzone/commons/suncalc/MoonIllumination.java | 2 +- .../org/shredzone/commons/suncalc/MoonPosition.java | 2 +- .../shredzone/commons/suncalc/MoonPositionTest.java | 10 ++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/doc/docs/migration.md b/src/doc/docs/migration.md index f32b22d..374da85 100644 --- a/src/doc/docs/migration.md +++ b/src/doc/docs/migration.md @@ -2,6 +2,9 @@ This document will help you migrate your code to the latest _suncalc_ version. +## Version 2.13 +* Due to a very old bug, `MoonPosition.getParallacticAngle()` gave completely wrong results. If you used that method in your code or tests, prepare to get totally different values now. + ## Version 2.10 * Due to a very old bug, setting the `height()` had almost no impact on the result, which is obviously wrong (on sunset, a plane in the sky is still illuminated while the sun has just gone at the viewer's position). This bug has been fixed. If you are using `height()`, you will get correct results now. They may deviate by several minutes from the results of earlier versions. diff --git a/src/main/java/org/shredzone/commons/suncalc/MoonIllumination.java b/src/main/java/org/shredzone/commons/suncalc/MoonIllumination.java index fc1d9e8..f8b42ed 100644 --- a/src/main/java/org/shredzone/commons/suncalc/MoonIllumination.java +++ b/src/main/java/org/shredzone/commons/suncalc/MoonIllumination.java @@ -102,7 +102,7 @@ public double getPhase() { *

* By subtracting {@link MoonPosition#getParallacticAngle()} from {@link #getAngle()}, * one can get the zenith angle of the moons bright limb (anticlockwise). The zenith - * angle can be used do draw the moon shape from the observers perspective (e.g. the + * angle can be used do draw the moon shape from the observer's perspective (e.g. the * moon lying on its back). */ public double getAngle() { diff --git a/src/main/java/org/shredzone/commons/suncalc/MoonPosition.java b/src/main/java/org/shredzone/commons/suncalc/MoonPosition.java index a39ed2f..3113de7 100644 --- a/src/main/java/org/shredzone/commons/suncalc/MoonPosition.java +++ b/src/main/java/org/shredzone/commons/suncalc/MoonPosition.java @@ -81,7 +81,7 @@ public MoonPosition execute() { double hRef = refraction(horizontal.getTheta()); - double pa = atan2(sin(h), tan(phi) * cos(mc.getTheta())) - sin(mc.getTheta()) * cos(h); + double pa = atan2(sin(h), tan(phi) * cos(mc.getTheta()) - sin(mc.getTheta()) * cos(h)); return new MoonPosition(horizontal.getPhi(), horizontal.getTheta() + hRef, mc.getR(), pa); } diff --git a/src/test/java/org/shredzone/commons/suncalc/MoonPositionTest.java b/src/test/java/org/shredzone/commons/suncalc/MoonPositionTest.java index a90dffd..358517c 100644 --- a/src/test/java/org/shredzone/commons/suncalc/MoonPositionTest.java +++ b/src/test/java/org/shredzone/commons/suncalc/MoonPositionTest.java @@ -36,6 +36,7 @@ public void testCologne() { .execute(); assertThat(mp1.getAzimuth()).as("azimuth").isCloseTo(304.8, ERROR); assertThat(mp1.getAltitude()).as("altitude").isCloseTo(-39.6, ERROR); + assertThat(mp1.getParallacticAngle()).as("pa").isCloseTo(32.0, ERROR); MoonPosition mp2 = MoonPosition.compute() .on(2017, 7, 12, 3, 51, 0) @@ -45,6 +46,7 @@ public void testCologne() { assertThat(mp2.getAzimuth()).as("azimuth").isCloseTo(179.9, ERROR); assertThat(mp2.getAltitude()).as("altitude").isCloseTo(25.3, ERROR); assertThat(mp2.getDistance()).as("distance").isCloseTo(394709.0, DISTANCE_ERROR); + assertThat(mp2.getParallacticAngle()).as("pa").isCloseTo(0.0, ERROR); } @Test @@ -56,6 +58,7 @@ public void testAlert() { .execute(); assertThat(mp1.getAzimuth()).as("azimuth").isCloseTo(257.5, ERROR); assertThat(mp1.getAltitude()).as("altitude").isCloseTo(-10.9, ERROR); + assertThat(mp1.getParallacticAngle()).as("pa").isCloseTo(7.5, ERROR); MoonPosition mp2 = MoonPosition.compute() .on(2017, 7, 12, 2, 37, 0) @@ -65,6 +68,7 @@ public void testAlert() { assertThat(mp2.getAzimuth()).as("azimuth").isCloseTo(179.8, ERROR); assertThat(mp2.getAltitude()).as("altitude").isCloseTo(-5.7, ERROR); assertThat(mp2.getDistance()).as("distance").isCloseTo(393609.0, DISTANCE_ERROR); + assertThat(mp2.getParallacticAngle()).as("pa").isCloseTo(0.0, ERROR); } @Test @@ -76,6 +80,7 @@ public void testWellington() { .execute(); assertThat(mp1.getAzimuth()).as("azimuth").isCloseTo(311.3, ERROR); assertThat(mp1.getAltitude()).as("altitude").isCloseTo(55.1, ERROR); + assertThat(mp1.getParallacticAngle()).as("pa").isCloseTo(144.2, ERROR); MoonPosition mp2 = MoonPosition.compute() .on(2017, 7, 12, 2, 17, 0) @@ -85,6 +90,7 @@ public void testWellington() { assertThat(mp2.getAzimuth()).as("azimuth").isCloseTo(0.5, ERROR); assertThat(mp2.getAltitude()).as("altitude").isCloseTo(63.9, ERROR); assertThat(mp2.getDistance()).as("distance").isCloseTo(396272.0, DISTANCE_ERROR); + assertThat(mp2.getParallacticAngle()).as("pa").isCloseTo(-179.6, ERROR); } @Test @@ -96,6 +102,7 @@ public void testPuertoWilliams() { .execute(); assertThat(mp1.getAzimuth()).as("azimuth").isCloseTo(199.4, ERROR); assertThat(mp1.getAltitude()).as("altitude").isCloseTo(-52.7, ERROR); + assertThat(mp1.getParallacticAngle()).as("pa").isCloseTo(168.3, ERROR); MoonPosition mp2 = MoonPosition.compute() .on(2017, 2, 7, 23, 4, 0) @@ -105,6 +112,7 @@ public void testPuertoWilliams() { assertThat(mp2.getAzimuth()).as("azimuth").isCloseTo(0.1, ERROR); assertThat(mp2.getAltitude()).as("altitude").isCloseTo(16.3, ERROR); assertThat(mp2.getDistance()).as("distance").isCloseTo(369731.0, DISTANCE_ERROR); + assertThat(mp2.getParallacticAngle()).as("pa").isCloseTo(-179.9, ERROR); } @Test @@ -116,6 +124,7 @@ public void testSingapore() { .execute(); assertThat(mp1.getAzimuth()).as("azimuth").isCloseTo(240.6, ERROR); assertThat(mp1.getAltitude()).as("altitude").isCloseTo(57.1, ERROR); + assertThat(mp1.getParallacticAngle()).as("pa").isCloseTo(64.0, ERROR); MoonPosition mp2 = MoonPosition.compute() .on(2017, 7, 12, 3, 11, 0) @@ -125,6 +134,7 @@ public void testSingapore() { assertThat(mp2.getAzimuth()).as("azimuth").isCloseTo(180.0, ERROR); assertThat(mp2.getAltitude()).as("altitude").isCloseTo(74.1, ERROR); assertThat(mp2.getDistance()).as("distance").isCloseTo(395621.0, DISTANCE_ERROR); + assertThat(mp2.getParallacticAngle()).as("pa").isCloseTo(0.0, ERROR); } }