Skip to content

Commit

Permalink
Fix Moon parallactic angle calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
shred committed Apr 10, 2023
1 parent 278d499 commit 58bb03d
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/doc/docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This document will help you migrate your code to the latest _suncalc_ version.

## Version 3.6
* 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 3.3
* 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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public double getPhase() {
* <p>
* 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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/org/shredzone/commons/suncalc/MoonPositionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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);
}

}

0 comments on commit 58bb03d

Please sign in to comment.