我正在将GCRS
个对象转换为半中心坐标,并发现在此变换下未保留两点之间的距离。
import astropy.units
import astropy.coordinates
import astropy.time
from numpy.linalg import norm
t = astropy.time.Time('1999-01-01T00:00:00.123456789')
def earth2galaxy(lat):
'''
Convert an Earth coordinate to a galactocentric coordinate.
'''
# get GCRS coordinates
earth = astropy.coordinates.EarthLocation(lat=lat*astropy.units.deg,
lon=0,
height=0)
pos, _ = earth.get_gcrs_posvel(obstime=t)
cartrep = astropy.coordinates.CartesianRepresentation(pos.xyz,
unit=astropy.units.m)
gcrs = astropy.coordinates.GCRS(cartrep)
# convert GCRS to galactocentric
gc = gcrs.transform_to(astropy.coordinates.Galactocentric)
return earth, gcrs, gc
earthA, gcrsA, gcA = earth2galaxy(0)
earthB, gcrsB, gcB = earth2galaxy(0.01)
print(norm(earthA-earthB))
print(norm(gcrsA.cartesian.xyz-gcrsB.cartesian.xyz))
print(norm(gcA.cartesian.xyz-gcB.cartesian.xyz))
此代码给出
1105.74275693
1105.74275232
971.796949054
我发现对于更大的距离(例如,纬度偏移为10s)而言,这不是问题。
我以前是通过给定点A
和B
–变换点A
和C = A + c*AB
来解决这个问题的,其中c
很大数。然后,我将通过撤消缩放B'
来恢复转换后的B' = A' + A'C' / c
。但是,感觉我应该解决问题的实际根源,而不是这种解决方法。
答案 0 :(得分:2)
这可能只是一个浮点精度问题。如果看一下笛卡尔值,对于GCRS帧,x
,y
和z
的顺序为1e6
,1e6
和1e2
,但对于银河帧,它们的顺序分别为1e20
,1e10
和1e17
。
鉴于8字节浮点数(1e-15
)的精度为numpy.finfo('f8').eps
,这意味着银河系坐标的x
值只能精确到{{1} }(米)。然后采用标准(以1e5
值不确定性为主导),也将导致x
米量级的精度,远超过实际间隔。
计算值仍然彼此接近这一事实在很大程度上是幸运的(尽管这有一个潜在的原因,例如偏差在某种程度上可以平均)。
这也符合以下事实:较大的偏移量不会出现问题(或出现的问题较少)。尽管自己进行了测试,但仍然看到1e5
〜1e4
顺序的差异。确切地说,使用0和10的纬度,我得到:
1e5
如果我的假设正确,那么我的建议很简单:为您的坐标使用适当的坐标系,并考虑相关的不确定性(机器精度和所用坐标系的精度)。
答案 1 :(得分:1)
我认为“ 0 0”通常会击中头部,但这种情况还有另一种解决方案:使用精度更高的float dtype-例如float128
dtype(您将其传递给dtype
的{{1}}关键字),可能距离将会更近。
不幸的是,有一个错误似乎迫使dtypes返回CartesianRepresentation
(我曾报道过:https://github.com/astropy/astropy/issues/8870),但是如果这个问题已经解决,则取决于您的计算机及其支持的精度。精度更高的dtype可以做到。