Python 变换后恢复角度

Python 变换后恢复角度,python,numpy,math,trigonometry,Python,Numpy,Math,Trigonometry,这似乎是一项相当简单的任务,但我没有找到解决方案,也没有什么想法 我用两个角度来定义一些变换系数。现在,我的真实数据中没有这些角度的值,我有系数,我需要恢复这些角度 我原以为函数会解决这个问题,但有时它无法恢复正确的a1角度,而是返回其180补码,这会影响a2角度的恢复 我做错了什么?如何正确恢复a1、a2角度 import numpy as np # Repeat 100 times for _ in range(100): # Define two random angles in

这似乎是一项相当简单的任务,但我没有找到解决方案,也没有什么想法

我用两个角度来定义一些变换系数。现在,我的真实数据中没有这些角度的值,我有系数,我需要恢复这些角度

我原以为函数会解决这个问题,但有时它无法恢复正确的
a1
角度,而是返回其
180
补码,这会影响
a2
角度的恢复

我做错了什么?如何正确恢复
a1、a2
角度

import numpy as np

# Repeat 100 times
for _ in range(100):
    # Define two random angles in the range [-pi, pi]. I do not have these
    # angles in my actual data, I have the A,B,C coefficients shown below.
    a1, a2 = np.random.uniform(-180., 180., (2,))

    # Transformation coefficients using the above angles.
    # This is the data I actually have.
    a1_rad, a2_rad = np.deg2rad(a1), np.deg2rad(a2)  # to radians
    A = - np.sin(a1_rad) * np.sin(a2_rad)
    B = np.cos(a1_rad) * np.sin(a2_rad)
    C = np.cos(a2_rad)

    # Recover a1 using 'arctan2' (returns angle in the range [-pi, pi])
    a1_recover = np.arctan2(-A / B, 1.)

    # Now obtain sin(a2), used below to obtain 'a2'
    sin_a2 = -A / np.sin(a1_recover)

    # Recover a2 using 'arctan2', where: C = cos(a2)
    a2_recover = np.arctan2(sin_a2, C)

    # Print differences.
    a1_recover = np.rad2deg(a1_recover)
    print("a1: {:.2f} = {} - {}".format(a1 - a1_recover, a1, a1_recover))
    a2_recover = np.rad2deg(a2_recover)
    print("a2: {:.2f} = {} - {}\n".format(a2 - a2_recover, a2, a2_recover))

您无法恢复角度符号信息,因为它在
A,B
计算(编队)中松动

sin/cos
符号的8种可能组合只给出了4个
A/B
符号的结果(并且
cos(a2)
的符号在这里没有帮助)


请注意,对于球坐标,当
a2_rad
等于0时,
(A,B,C)
等于
(0,0,1)
时,倾角范围仅为
0..Pi

,无论
a1_rad
等于多少。因此,转换不是1对1。因此,没有明确定义的逆

def ABC(a1, a2):
    a1_rad, a2_rad = np.deg2rad(a1), np.deg2rad(a2)  # to radians
    A = - np.sin(a1_rad) * np.sin(a2_rad)
    B = np.cos(a1_rad) * np.sin(a2_rad)
    C = np.cos(a2_rad)
    return A, B, C

print(ABC(0, 0))
# (-0.0, 0.0, 1.0)
print(90, 0)
# (-0.0, 0.0, 1.0)
print(-90, 0)
# (-0.0, 0.0, 1.0)
类似的问题也发生在相反(南极)的地方。在浮点精度的限制范围内,所有这些值(形式为
ABC(a1,180)
)也基本相同:

ABC(1, 180)
# (-2.1373033680837913e-18, 1.2244602795081332e-16, -1.0)

ABC(0, 180)
# (-0.0, 1.2246467991473532e-16, -1.0)

ABC(90, 180)
# (-1.2246467991473532e-16, 7.498798913309288e-33, -1.0)

您可以将
a1
a2
视为单位球体上的坐标,其中
a1
表示远离x轴的角度(通常称为
theta
)和
a2
表示远离z轴的角度(通常称为
phi

A
B
C
表示笛卡尔坐标系中单位球体上的同一点

通常将
a1
限制在
[0,2*pi)
范围内,将
a2
限制在
[0,pi]
范围内。 即使有这样的限制,北极和南极也有不止一个(实际上是无限数量的)有效表示。

您应该使用np.arctan2(-A,B)而不是np.arctan2(-A/B,1.)。使用后者,您将丢失信息:A=-1和B=1将给出与A-1和B=-1相同的结果,因此有时会出现180个不匹配。
如果将a2限制在(0180)中,则可以恢复角度。请注意,使用此限制,a2可以恢复为acos(C)。(我已经尝试过此方法,但由于我的程序是在C中,因此可能没有帮助)

所以你想找到
a1
a2
给定的
A
B
C
?确切地说,我想恢复
a1,a2=np.random.uniform(-180,180,2,)中定义的精确值
谢谢。我认为这是一个退化解决方案的问题,无法唯一解决,您的回答清楚地解释了这一点。