From 4f387e5fda22a15ed38e2efe71b2ffb83d1ae387 Mon Sep 17 00:00:00 2001 From: Don Cross Date: Sat, 16 Apr 2022 16:23:35 -0400 Subject: [PATCH] Kotlin: added heliocentric/topocentric state vector tests. --- generate/template/astronomy.kt | 20 ++++++++++++ source/kotlin/doc/-state-vector/index.md | 2 ++ source/kotlin/doc/-state-vector/minus.md | 8 +++++ .../kotlin/doc/-state-vector/unary-minus.md | 8 +++++ .../github/cosinekitty/astronomy/astronomy.kt | 20 ++++++++++++ .../io/github/cosinekitty/astronomy/Tests.kt | 32 ++++++++++++++++++- 6 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 source/kotlin/doc/-state-vector/minus.md create mode 100644 source/kotlin/doc/-state-vector/unary-minus.md diff --git a/generate/template/astronomy.kt b/generate/template/astronomy.kt index d6e47667..adc1d997 100644 --- a/generate/template/astronomy.kt +++ b/generate/template/astronomy.kt @@ -921,6 +921,20 @@ data class StateVector( verifyIdenticalTimes(t, other.t) ) + /** + * Subtracts two state vetors, yielding the state vector difference. + */ + operator fun minus(other: StateVector) = + StateVector( + x - other.x, + y - other.y, + z - other.z, + vx - other.vx, + vy - other.vy, + vz - other.vz, + verifyIdenticalTimes(t, other.t) + ) + /** * Divides a state vector by a scalar. */ @@ -934,6 +948,12 @@ data class StateVector( vz / denom, t ) + + /** + * Negates a state vector; the same as multiplying the state vector by the scalar -1. + */ + operator fun unaryMinus() = + StateVector(-x, -y, -z, -vx, -vy, -vz, t) } diff --git a/source/kotlin/doc/-state-vector/index.md b/source/kotlin/doc/-state-vector/index.md index d9901b39..35bfa25a 100644 --- a/source/kotlin/doc/-state-vector/index.md +++ b/source/kotlin/doc/-state-vector/index.md @@ -19,8 +19,10 @@ Represents a combined position vector and velocity vector at a given moment in t | Name | Summary | |---|---| | [div](div.md) | [jvm]
operator fun [div](div.md)(denom: [Double](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-double/index.html)): [StateVector](index.md)
Divides a state vector by a scalar. | +| [minus](minus.md) | [jvm]
operator fun [minus](minus.md)(other: [StateVector](index.md)): [StateVector](index.md)
Subtracts two state vetors, yielding the state vector difference. | | [plus](plus.md) | [jvm]
operator fun [plus](plus.md)(other: [StateVector](index.md)): [StateVector](index.md)
Adds two state vetors, yielding the state vector sum. | | [position](position.md) | [jvm]
fun [position](position.md)(): [Vector](../-vector/index.md)
Returns the position vector associated with this state vector. | +| [unaryMinus](unary-minus.md) | [jvm]
operator fun [unaryMinus](unary-minus.md)(): [StateVector](index.md)
Negates a state vector; the same as multiplying the state vector by the scalar -1. | | [velocity](velocity.md) | [jvm]
fun [velocity](velocity.md)(): [Vector](../-vector/index.md)
Returns the velocity vector associated with this state vector. | ## Properties diff --git a/source/kotlin/doc/-state-vector/minus.md b/source/kotlin/doc/-state-vector/minus.md new file mode 100644 index 00000000..53292231 --- /dev/null +++ b/source/kotlin/doc/-state-vector/minus.md @@ -0,0 +1,8 @@ +//[astronomy](../../../index.md)/[io.github.cosinekitty.astronomy](../index.md)/[StateVector](index.md)/[minus](minus.md) + +# minus + +[jvm]\ +operator fun [minus](minus.md)(other: [StateVector](index.md)): [StateVector](index.md) + +Subtracts two state vetors, yielding the state vector difference. diff --git a/source/kotlin/doc/-state-vector/unary-minus.md b/source/kotlin/doc/-state-vector/unary-minus.md new file mode 100644 index 00000000..579d3c54 --- /dev/null +++ b/source/kotlin/doc/-state-vector/unary-minus.md @@ -0,0 +1,8 @@ +//[astronomy](../../../index.md)/[io.github.cosinekitty.astronomy](../index.md)/[StateVector](index.md)/[unaryMinus](unary-minus.md) + +# unaryMinus + +[jvm]\ +operator fun [unaryMinus](unary-minus.md)(): [StateVector](index.md) + +Negates a state vector; the same as multiplying the state vector by the scalar -1. diff --git a/source/kotlin/src/main/kotlin/io/github/cosinekitty/astronomy/astronomy.kt b/source/kotlin/src/main/kotlin/io/github/cosinekitty/astronomy/astronomy.kt index 905f5226..6ec53a5c 100644 --- a/source/kotlin/src/main/kotlin/io/github/cosinekitty/astronomy/astronomy.kt +++ b/source/kotlin/src/main/kotlin/io/github/cosinekitty/astronomy/astronomy.kt @@ -921,6 +921,20 @@ data class StateVector( verifyIdenticalTimes(t, other.t) ) + /** + * Subtracts two state vetors, yielding the state vector difference. + */ + operator fun minus(other: StateVector) = + StateVector( + x - other.x, + y - other.y, + z - other.z, + vx - other.vx, + vy - other.vy, + vz - other.vz, + verifyIdenticalTimes(t, other.t) + ) + /** * Divides a state vector by a scalar. */ @@ -934,6 +948,12 @@ data class StateVector( vz / denom, t ) + + /** + * Negates a state vector; the same as multiplying the state vector by the scalar -1. + */ + operator fun unaryMinus() = + StateVector(-x, -y, -z, -vx, -vy, -vz, t) } diff --git a/source/kotlin/src/test/kotlin/io/github/cosinekitty/astronomy/Tests.kt b/source/kotlin/src/test/kotlin/io/github/cosinekitty/astronomy/Tests.kt index c7375393..e9b98537 100644 --- a/source/kotlin/src/test/kotlin/io/github/cosinekitty/astronomy/Tests.kt +++ b/source/kotlin/src/test/kotlin/io/github/cosinekitty/astronomy/Tests.kt @@ -389,7 +389,8 @@ class Tests { // I used the Python version to calculate reference state vectors. // This is just a sanity check. - // More exhaustive tests will be added later. + // Exhaustive tests referenced against JPL Horizons data + // are done separately by the test `Heliocentric state vectors`. verifyHelio( Body.Mercury, @@ -1547,5 +1548,34 @@ class Tests { verifyStateBody("barystate/GeoEMB.txt", 4.076e-05, 5.335e-05) { time -> geoEmbState(time) } } + @Test + fun `Heliocentric state vectors`() { + verifyStateBody("heliostate/SSB.txt", -1.209e-05, -1.125e-07) { time -> helioState(Body.SSB, time) } + verifyStateBody("heliostate/Mercury.txt", 1.481e-04, 2.756e-04) { time -> helioState(Body.Mercury, time) } + verifyStateBody("heliostate/Venus.txt", 3.528e-05, 4.485e-05) { time -> helioState(Body.Venus, time) } + verifyStateBody("heliostate/Earth.txt", 1.476e-05, 6.105e-05) { time -> helioState(Body.Earth, time) } + verifyStateBody("heliostate/Mars.txt", 3.154e-05, 5.603e-05) { time -> helioState(Body.Mars, time) } + verifyStateBody("heliostate/Jupiter.txt", 7.455e-05, 2.562e-04) { time -> helioState(Body.Jupiter, time) } + verifyStateBody("heliostate/Saturn.txt", 1.066e-04, 3.150e-04) { time -> helioState(Body.Saturn, time) } + verifyStateBody("heliostate/Uranus.txt", 9.034e-05, 2.712e-04) { time -> helioState(Body.Uranus, time) } + verifyStateBody("heliostate/Neptune.txt", 9.834e-05, 4.534e-04) { time -> helioState(Body.Neptune, time) } + verifyStateBody("heliostate/Pluto.txt", 4.271e-05, 1.198e-04) { time -> helioState(Body.Pluto, time) } + verifyStateBody("heliostate/Moon.txt", 1.477e-05, 6.195e-05) { time -> helioState(Body.Moon, time) } + verifyStateBody("heliostate/EMB.txt", 1.476e-05, 6.106e-05) { time -> helioState(Body.EMB, time) } + } + + @Test + fun `Topocentric state vectors`() { + val observer = Observer(30.0, -80.0, 1000.0) + + verifyStateBody("topostate/Earth_N30_W80_1000m.txt", 2.108e-04, 2.430e-04) { + time -> -observer.toStateVector(time, EquatorEpoch.J2000) + } + + verifyStateBody("topostate/EMB_N30_W80_1000m.txt", 7.195e-04, 2.497e-04) { + time -> geoEmbState(time) - observer.toStateVector(time, EquatorEpoch.J2000) + } + } + //---------------------------------------------------------------------------------------- }