Source

exoplanets.ts

  1. /**
  2. @module Exoplanets
  3. */
  4. import {
  5. AstronomicalUnit,
  6. Day,
  7. Degree,
  8. EquatorialCoordinates,
  9. GeographicCoordinates,
  10. JulianDay,
  11. JupiterRadius,
  12. Kilometer,
  13. Radian,
  14. SolarRadius
  15. } from '@/types'
  16. import { DEG2RAD, ONE_UA_IN_KILOMETERS, PI, PIHALF, RAD2DEG } from '@/constants'
  17. import { getLocalSiderealTime } from '@/juliandays'
  18. import { Jupiter } from '@/planets'
  19. import { Sun } from '@/sun'
  20. /**
  21. * Simple helper to find the Julian Day of the next transit after the given lower Julian Day
  22. * @param {Number} lowerJD The lower julian day limit
  23. * @param {Number} orbitalPeriod The orbital period of the system, in days.
  24. * @param {Number} tZeroOfTransit The Julian Day of the primary|secondary transit.
  25. * @returns {Number} The Julian Day of the next transit.
  26. */
  27. export function julianDayOfNextTransit (lowerJD: JulianDay, orbitalPeriod: Day, tZeroOfTransit: JulianDay) {
  28. const n = Math.floor(1 + (lowerJD / orbitalPeriod) - (tZeroOfTransit / orbitalPeriod))
  29. return tZeroOfTransit + (n * orbitalPeriod)
  30. }
  31. /**
  32. * Compute the details of an exoplanet transit
  33. * @param orbitalPeriod
  34. * @param lambdaAngle
  35. * @param timeOfPeriastron
  36. * @param eccentricity
  37. * @param radius
  38. * @param semiMajorAxis
  39. * @param parentStarRadius
  40. */
  41. export function getExoplanetTransitDetails (orbitalPeriod: Day,
  42. lambdaAngle: Degree,
  43. timeOfPeriastron: JulianDay,
  44. eccentricity: number,
  45. radius: JupiterRadius,
  46. semiMajorAxis: AstronomicalUnit,
  47. parentStarRadius: SolarRadius) {
  48. let f = PIHALF - lambdaAngle * DEG2RAD
  49. const e = eccentricity
  50. const P = orbitalPeriod
  51. const E = 2 * (Math.atan(Math.sqrt((1 - e) / (1 + e))) * Math.tan(f / 2))
  52. const Rstar: Kilometer = parentStarRadius * Sun.constants.equatorialRadius
  53. const Rplanet: Kilometer = radius * Jupiter.constants.equatorialRadius
  54. const a: Kilometer = semiMajorAxis * ONE_UA_IN_KILOMETERS
  55. const df: Radian = Math.asin(((Rstar + Rplanet) / a) / (1 - e * Math.cos(E)))
  56. f = f + df
  57. const M = E - e * Math.sin(E)
  58. // const t_M = P*M/(2*Math.PI)
  59. const duration = P * M / PI
  60. const cycleCenter = P / (2 * PI) * (E - e * Math.sin(E))
  61. const center = timeOfPeriastron + cycleCenter
  62. const start = center - duration / 2
  63. const end = center + duration / 2
  64. return { duration, start, center, end }
  65. }
  66. // If transitJD is undefined, the altitude of the transit to the local meridian will be computed.
  67. // If transitJD is provided, it is assumed to be the JD of which we want the local altitude.
  68. // It can be that of a transit... or not.
  69. export function getTransitAltitude (equCoords: EquatorialCoordinates, geoCoords: GeographicCoordinates, transitJD: JulianDay | undefined = undefined): Degree {
  70. // See AA. P.93 eq. 13.6 (and p.92 for H).
  71. let cosH = 1
  72. if (transitJD !== undefined && transitJD !== null) {
  73. const lmst = getLocalSiderealTime(transitJD, geoCoords.longitude)
  74. cosH = Math.cos((lmst - equCoords.rightAscension) * DEG2RAD)
  75. }
  76. const dlat = geoCoords.latitude * DEG2RAD
  77. const ddec = geoCoords.latitude * DEG2RAD
  78. return Math.asin(
  79. Math.sin(dlat) * Math.sin(ddec) + Math.cos(dlat) * Math.cos(ddec) * cosH
  80. ) * RAD2DEG
  81. }