mirror of
https://github.com/cosinekitty/astronomy.git
synced 2026-05-19 14:27:52 -04:00
Kotlin: convert AstroVector to Observer.
Added `AstroVector.toObserver`, which converts a geocentric equatorial vector (EQJ or EQD) into a geographic location in an `Observer` object.
This commit is contained in:
@@ -699,13 +699,39 @@ data class AstroVector(
|
||||
sphere.dist
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the geographic location corresponding to a geocentric equatorial vector.
|
||||
*
|
||||
* This is the inverse function of [Observer.toVector].
|
||||
* Given an equatorial vector from the center of the Earth to
|
||||
* an observer on or near the Earth's surface, this function returns
|
||||
* the geographic latitude, longitude, and elevation for that observer.
|
||||
*
|
||||
* @param equator
|
||||
* Selects the date of the Earth's equator in which this vector is expressed.
|
||||
* The caller may select [EquatorEpoch.J2000] to use the orientation of the Earth's equator
|
||||
* at noon UTC on January 1, 2000, in which case this function corrects for precession
|
||||
* and nutation of the Earth as it was at the moment specified by the time `this.t`.
|
||||
* Or the caller may select [EquatorEpoch.OfDate] to use the Earth's equator at `this.t`
|
||||
* as the orientation.
|
||||
*
|
||||
* @return The geographic coordinates corresponding to the vector.
|
||||
*/
|
||||
fun toObserver(equator: EquatorEpoch): Observer {
|
||||
val vector = when(equator) {
|
||||
EquatorEpoch.J2000 -> gyration(this, PrecessDirection.From2000)
|
||||
EquatorEpoch.OfDate -> this
|
||||
}
|
||||
return inverseTerra(vector)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a scalar by a vector, yielding another vector.
|
||||
*/
|
||||
operator fun Double.times(vec: AstroVector) =
|
||||
AstroVector(this*vec.x, this*vec.y, this*vec.z, vec.t)
|
||||
AstroVector(this*vec.x, this*vec.y, this*vec.z, vec.t)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,7 @@ A 3D Cartesian vector whose components are expressed in Astronomical Units (AU).
|
||||
| [plus](plus.md) | [jvm]<br>operator fun [plus](plus.md)(other: [AstroVector](index.md)): [AstroVector](index.md)<br>Adds two vectors. Both operands must have identical times. |
|
||||
| [toEquatorial](to-equatorial.md) | [jvm]<br>fun [toEquatorial](to-equatorial.md)(): [Equatorial](../-equatorial/index.md)<br>Given an equatorial vector, calculates equatorial angular coordinates. |
|
||||
| [toHorizontal](to-horizontal.md) | [jvm]<br>fun [toHorizontal](to-horizontal.md)(refraction: [Refraction](../-refraction/index.md)): [Spherical](../-spherical/index.md)<br>Converts Cartesian coordinates to horizontal coordinates. |
|
||||
| [toObserver](to-observer.md) | [jvm]<br>fun [toObserver](to-observer.md)(equator: [EquatorEpoch](../-equator-epoch/index.md)): [Observer](../-observer/index.md)<br>Calculates the geographic location corresponding to a geocentric equatorial vector. |
|
||||
| [toSpherical](to-spherical.md) | [jvm]<br>fun [toSpherical](to-spherical.md)(): [Spherical](../-spherical/index.md)<br>Converts Cartesian coordinates to spherical coordinates. |
|
||||
| [unaryMinus](unary-minus.md) | [jvm]<br>operator fun [unaryMinus](unary-minus.md)(): [AstroVector](index.md)<br>Negates a vector; the same as multiplying the vector by the scalar -1. |
|
||||
|
||||
|
||||
22
source/kotlin/doc/-astro-vector/to-observer.md
Normal file
22
source/kotlin/doc/-astro-vector/to-observer.md
Normal file
@@ -0,0 +1,22 @@
|
||||
//[astronomy](../../../index.md)/[io.github.cosinekitty.astronomy](../index.md)/[AstroVector](index.md)/[toObserver](to-observer.md)
|
||||
|
||||
# toObserver
|
||||
|
||||
[jvm]\
|
||||
fun [toObserver](to-observer.md)(equator: [EquatorEpoch](../-equator-epoch/index.md)): [Observer](../-observer/index.md)
|
||||
|
||||
Calculates the geographic location corresponding to a geocentric equatorial vector.
|
||||
|
||||
This is the inverse function of [Observer.toVector](../-observer/to-vector.md). Given an equatorial vector from the center of the Earth to an observer on or near the Earth's surface, this function returns the geographic latitude, longitude, and elevation for that observer.
|
||||
|
||||
#### Return
|
||||
|
||||
The geographic coordinates corresponding to the vector.
|
||||
|
||||
## Parameters
|
||||
|
||||
jvm
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| equator | Selects the date of the Earth's equator in which this vector is expressed. The caller may select [EquatorEpoch.J2000] to use the orientation of the Earth's equator at noon UTC on January 1, 2000, in which case this function corrects for precession and nutation of the Earth as it was at the moment specified by the time `this.t`. Or the caller may select [EquatorEpoch.OfDate] to use the Earth's equator at `this.t` as the orientation. |
|
||||
@@ -13,7 +13,7 @@ The caller may pass a value in equator to select either [EquatorEpoch.J2000](../
|
||||
|
||||
The returned vector has components expressed in astronomical units (AU). To convert to kilometers, multiply the vector values by the scalar value [KM_PER_AU](../-k-m_-p-e-r_-a-u.md).
|
||||
|
||||
The inverse of this function is also available: AstroVector.toObserver.
|
||||
The inverse of this function is also available: [AstroVector.toObserver](../-astro-vector/to-observer.md).
|
||||
|
||||
#### Return
|
||||
|
||||
|
||||
@@ -699,13 +699,39 @@ data class AstroVector(
|
||||
sphere.dist
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the geographic location corresponding to a geocentric equatorial vector.
|
||||
*
|
||||
* This is the inverse function of [Observer.toVector].
|
||||
* Given an equatorial vector from the center of the Earth to
|
||||
* an observer on or near the Earth's surface, this function returns
|
||||
* the geographic latitude, longitude, and elevation for that observer.
|
||||
*
|
||||
* @param equator
|
||||
* Selects the date of the Earth's equator in which this vector is expressed.
|
||||
* The caller may select [EquatorEpoch.J2000] to use the orientation of the Earth's equator
|
||||
* at noon UTC on January 1, 2000, in which case this function corrects for precession
|
||||
* and nutation of the Earth as it was at the moment specified by the time `this.t`.
|
||||
* Or the caller may select [EquatorEpoch.OfDate] to use the Earth's equator at `this.t`
|
||||
* as the orientation.
|
||||
*
|
||||
* @return The geographic coordinates corresponding to the vector.
|
||||
*/
|
||||
fun toObserver(equator: EquatorEpoch): Observer {
|
||||
val vector = when(equator) {
|
||||
EquatorEpoch.J2000 -> gyration(this, PrecessDirection.From2000)
|
||||
EquatorEpoch.OfDate -> this
|
||||
}
|
||||
return inverseTerra(vector)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a scalar by a vector, yielding another vector.
|
||||
*/
|
||||
operator fun Double.times(vec: AstroVector) =
|
||||
AstroVector(this*vec.x, this*vec.y, this*vec.z, vec.t)
|
||||
AstroVector(this*vec.x, this*vec.y, this*vec.z, vec.t)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1074,4 +1074,41 @@ class Tests {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
private fun VerifyGeoid(observer: Observer, time: AstroTime, equator: EquatorEpoch) {
|
||||
val degreeTolerance = 1.0e-12
|
||||
val meterTolerance = 1.0e-8
|
||||
val vector = observer.toVector(time, equator)
|
||||
val check = vector.toObserver(equator)
|
||||
val latDiff = abs(check.latitude - observer.latitude)
|
||||
val lonDiff = dcos(observer.latitude) * abs(check.longitude - observer.longitude)
|
||||
val heightDiff = abs(check.height - observer.height)
|
||||
assertTrue(latDiff < degreeTolerance, "excessive latitude error = $latDiff")
|
||||
assertTrue(lonDiff < degreeTolerance, "excessive longitude error = $lonDiff")
|
||||
assertTrue(heightDiff < meterTolerance, "excessive height error = $heightDiff")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Verify inverse geoid calculations`() {
|
||||
// Calculate position vectors for a variety of geographic coordinates.
|
||||
// Verify that we can convert each observer back into a matching vector.
|
||||
val time = AstroTime(8134.392799058808) // 2022-04-09T21:25:37.839Z
|
||||
var latitude = -85.0
|
||||
while (latitude <= +85.0) {
|
||||
var longitude = -175.0
|
||||
while (longitude <= +175.0) {
|
||||
var height = -5000.0
|
||||
while (height <= +5000.0) {
|
||||
val observer = Observer(latitude, longitude, height)
|
||||
VerifyGeoid(observer, time, EquatorEpoch.OfDate)
|
||||
VerifyGeoid(observer, time, EquatorEpoch.J2000)
|
||||
height += 1000.0
|
||||
}
|
||||
longitude += 5.0
|
||||
}
|
||||
latitude += 5.0
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user