如何计算正确的行星冲日?
How do I compute correct planet oppositions?
我很难找到一种方法来计算行星冲日的确切时刻。根据定义,当从地球 的角度来看,行星 与太阳 相对时,行星 被称为冲日,所以我的假设是它发生在角度 处于最大值的时刻。
为了找到这个,我用 Skyfield 写了下面的代码:
def get_skf_objects():
return get_loader()('de421.bsp')
def get_angle(time: Time):
sun_pos = earth.at(time).observe(get_skf_objects()['sun'])
aster_pos = earth.at(time).observe(get_skf_objects()[aster.skyfield_name]) # e.g. aster.skyfield_name = 'MARS'
degrees = sun_pos.separation_from(aster_pos).degrees
return degrees
get_angle.rough_period = 1.0
times, angles = _find_maxima(start_time, end_time, get_angle, epsilon=1./3600/24)
出于某些我不太明白的原因,这会在反对实际发生的时候产生价值。但我真正的问题是,与真正的反对时间相比,我得到的时间总是假的。例如:
- 2018 年 7 月 27 日的火星冲日被指定为 2:15 UTC,但实际上,它实际上是 5:12 UTC。
- 2020 年 10 月 13 日的火星冲日将发生在 23:59 UTC,但 Skyfield 告诉我它将发生在 10 月 14 日 01:55 UTC。
等等……
我在 get_angle
中的 degrees
变量和 _find_maxima()
调用后的 angles
上添加了打印调用,并在 10 月 14 日得到了这个结果:
[177.00547411 177.00728148 177.00435833 176.99671953 176.98440208
176.96746426 176.94598429 176.92005866 176.88980009 176.85533528
176.81680257 176.77434952]
[177.00547411 177.00615453 177.00667867 177.00704644 177.00725779
177.00731269 177.00721115 177.00695318 177.00653883 177.00596817
177.00524129 177.00435833]
[177.00725779 177.00727941 177.00729586 177.00730713 177.00731323
177.00731417 177.00730993 177.00730051 177.00728593 177.00726617
177.00724125 177.00721115]
[177.00731323 177.00731379 177.00731417 177.00731438 177.00731443
177.0073143 177.00731399 177.00731352 177.00731288 177.00731207
177.00731108 177.00730993]
[177.00731438 177.0073144 177.00731442 177.00731443 177.00731443
177.00731443 177.00731442 177.00731441 177.00731439 177.00731436
177.00731433 177.0073143 ]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443]
发生了什么事?
您的方向是正确的,但是您的方法存在一些问题。
你反对的确切时间的来源(你有提到来源吗?如果是那么我还没有在你的问题的文本中找到它)似乎是一个不正确的。 2020 年火星冲日的确切时间是 23:25 UT,您可以在 this Google Books link.
验证
您猜测将使用原始分离角定义对立面很接近但不准确。根据this article on the Wikipedia,冲日是太阳与行星的黄经相差180°的时刻。除其他外,这个定义意味着在过去,可以通过从行星经度 table 中减去两个角度来找到对冲力矩,而涉及原始 angular 分离的定义则需要球面三角学在一对 lat-lon(或 RA-dec)坐标之间。
定义,碰巧使用视位置,所以你需要调用.apparent()
来转换你收到的坐标。
将这些调整放在一起,看看以下脚本是否为您提供了正确答案:
from skyfield.api import load, tau, pi
from skyfield.almanac import find_discrete
planets = load('de421.bsp')
sun = planets['sun']
earth = planets['earth']
mars = planets['mars']
ts = load.timescale(builtin=True)
def longitude_difference(t):
e = earth.at(t)
s = e.observe(sun).apparent()
m = e.observe(mars).apparent()
_, lon1, _ = s.ecliptic_latlon()
_, lon2, _ = m.ecliptic_latlon()
return (lon1.degrees - lon2.degrees) - 180 > 0
longitude_difference.rough_period = 300.0
t, b = find_discrete(ts.utc(2020), ts.utc(2021), longitude_difference)
for ti in t:
print(t.utc_jpl())
我很难找到一种方法来计算行星冲日的确切时刻。根据定义,当从地球
为了找到这个,我用 Skyfield 写了下面的代码:
def get_skf_objects():
return get_loader()('de421.bsp')
def get_angle(time: Time):
sun_pos = earth.at(time).observe(get_skf_objects()['sun'])
aster_pos = earth.at(time).observe(get_skf_objects()[aster.skyfield_name]) # e.g. aster.skyfield_name = 'MARS'
degrees = sun_pos.separation_from(aster_pos).degrees
return degrees
get_angle.rough_period = 1.0
times, angles = _find_maxima(start_time, end_time, get_angle, epsilon=1./3600/24)
出于某些我不太明白的原因,这会在反对实际发生的时候产生价值。但我真正的问题是,与真正的反对时间相比,我得到的时间总是假的。例如:
- 2018 年 7 月 27 日的火星冲日被指定为 2:15 UTC,但实际上,它实际上是 5:12 UTC。
- 2020 年 10 月 13 日的火星冲日将发生在 23:59 UTC,但 Skyfield 告诉我它将发生在 10 月 14 日 01:55 UTC。
等等……
我在 get_angle
中的 degrees
变量和 _find_maxima()
调用后的 angles
上添加了打印调用,并在 10 月 14 日得到了这个结果:
[177.00547411 177.00728148 177.00435833 176.99671953 176.98440208
176.96746426 176.94598429 176.92005866 176.88980009 176.85533528
176.81680257 176.77434952]
[177.00547411 177.00615453 177.00667867 177.00704644 177.00725779
177.00731269 177.00721115 177.00695318 177.00653883 177.00596817
177.00524129 177.00435833]
[177.00725779 177.00727941 177.00729586 177.00730713 177.00731323
177.00731417 177.00730993 177.00730051 177.00728593 177.00726617
177.00724125 177.00721115]
[177.00731323 177.00731379 177.00731417 177.00731438 177.00731443
177.0073143 177.00731399 177.00731352 177.00731288 177.00731207
177.00731108 177.00730993]
[177.00731438 177.0073144 177.00731442 177.00731443 177.00731443
177.00731443 177.00731442 177.00731441 177.00731439 177.00731436
177.00731433 177.0073143 ]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443]
发生了什么事?
您的方向是正确的,但是您的方法存在一些问题。
你反对的确切时间的来源(你有提到来源吗?如果是那么我还没有在你的问题的文本中找到它)似乎是一个不正确的。 2020 年火星冲日的确切时间是 23:25 UT,您可以在 this Google Books link.
验证
您猜测将使用原始分离角定义对立面很接近但不准确。根据this article on the Wikipedia,冲日是太阳与行星的黄经相差180°的时刻。除其他外,这个定义意味着在过去,可以通过从行星经度 table 中减去两个角度来找到对冲力矩,而涉及原始 angular 分离的定义则需要球面三角学在一对 lat-lon(或 RA-dec)坐标之间。
定义,碰巧使用视位置,所以你需要调用
.apparent()
来转换你收到的坐标。
将这些调整放在一起,看看以下脚本是否为您提供了正确答案:
from skyfield.api import load, tau, pi
from skyfield.almanac import find_discrete
planets = load('de421.bsp')
sun = planets['sun']
earth = planets['earth']
mars = planets['mars']
ts = load.timescale(builtin=True)
def longitude_difference(t):
e = earth.at(t)
s = e.observe(sun).apparent()
m = e.observe(mars).apparent()
_, lon1, _ = s.ecliptic_latlon()
_, lon2, _ = m.ecliptic_latlon()
return (lon1.degrees - lon2.degrees) - 180 > 0
longitude_difference.rough_period = 300.0
t, b = find_discrete(ts.utc(2020), ts.utc(2021), longitude_difference)
for ti in t:
print(t.utc_jpl())