缘起
在工作中要将激光雷达的3D点云进行球面投影得到2D图像,这就要将笛卡尔空间坐标系中的点 P c = ( x , y , z ) P_c=(x, y, z) Pc=(x,y,z)表示成球体坐标系中的形式 P s = ( θ , ϕ , r ) P_s=(\theta, \phi, r) Ps=(θ,ϕ,r),

其中:
θ
=
a
r
c
t
a
n
(
y
x
)
ϕ
=
a
r
c
s
i
n
(
z
r
)
r
=
x
2
+
y
2
+
z
2
\theta=arctan(\frac{y}{x}) \\ \phi=arcsin(\frac{z}{r}) \\ r=\sqrt{x^2+y^2+z^2}
θ=arctan(xy)ϕ=arcsin(rz)r=x2+y2+z2
这就要用到相关函数来求
θ
\theta
θ,
ϕ
\phi
ϕ,
r
r
r的值。根据球坐标的定义,要求
θ
∈
[
−
π
,
π
]
\theta\in[-\pi, \pi]
θ∈[−π,π],
ϕ
∈
[
−
π
2
,
π
2
]
\phi\in[-\frac{\pi}{2},\frac{\pi}{2} ]
ϕ∈[−2π,2π],
r
∈
[
0
,
+
∞
)
r\in[0, +\infty)
r∈[0,+∞)。其中
ϕ
\phi
ϕ由反正弦函数
y
=
a
r
c
s
i
n
(
x
)
y=arcsin(x)
y=arcsin(x)得到,它的定义域是
[
−
1
,
1
]
[-1,1]
[−1,1],值域是
[
−
π
2
,
π
2
]
[-\frac{\pi}{2}, \frac{\pi}{2}]
[−2π,2π],符合要求,
r
r
r是一个二范数,一定大于等于
0
0
0,满足球坐标定义的要求。但是对于
θ
\theta
θ就有些麻烦了,我们知道正切函数的周期是
π
\pi
π,因此反正切函数一般也只取一个周期,
y
=
a
r
c
t
a
n
(
x
)
y=arctan(x)
y=arctan(x)的定义域是
R
\mathbb{R}
R,值域是
(
−
π
2
,
π
2
)
(-\frac{\pi}{2}, \frac{\pi}{2})
(−2π,2π),但是我们的要求是
θ
∈
[
−
π
,
π
]
\theta\in[-\pi, \pi]
θ∈[−π,π]呀!
别担心,Numpy早就贴心的准备好解决办法了,它不仅有np.arctan()函数,还准备了np.arctan2()函数,能够满足我们的需求。下面就来看看这两个函数有什么区别。
arctan和arctan2详情
arctan
查看说明文档
import numpy as np
np.arctan??
Call signature: np.arctan(*args, **kwargs)
Type: ufunc
String form: <ufunc ‘arctan’>
File: ~/anaconda3/envs/torch/lib/python3.7/site-packages/numpy/init.py
Docstring:
arctan(x, /, out=None, *, where=True, casting=‘same_kind’, order=‘K’, dtype=None, subok=True[, signature, extobj])
Trigonometric inverse tangent, element-wise.
The inverse of tan, so that ify = tan(x)
thenx = arctan(y)
.
…(中间其他内容按下不表,有兴趣的同学可自行查看说明文档,只看out部分)
out : ndarray or scalar
Out has the same shape asx
. Its real part is in
[-pi/2, pi/2]
(arctan(+/-inf)
returns+/-pi/2
).
This is a scalar ifx
is a scalar.
总结:
- arctan是tan的反函数, 输入标量或者数组,输出标量或者数组.输入正切值,输出对应弧度。
- arctan的值域是 [ − π 2 , π 2 ] [-\frac{\pi}{2}, \frac{\pi}{2}] [−2π,2π]
arctan2
查看说明文档
import numpy as np
np.arctan2??
Call signature: np.arctan2(*args, **kwargs)
Type: ufunc
String form: <ufunc ‘arctan2’>
File: ~/anaconda3/envs/torch/lib/python3.7/site-packages/numpy/init.py
Docstring:
arctan2(x1, x2, /, out=None, *, where=True, casting=‘same_kind’, order=‘K’, dtype=None, subok=True[, signature, extobj])
Element-wise arc tangent ofx1/x2
choosing the quadrant correctly.
The quadrant (i.e., branch) is chosen so thatarctan2(x1, x2)
is
the signed angle in radians between the ray ending at the origin and
passing through the point (1,0), and the ray ending at the origin and
passing through the point (x2
,x1
). (Note the role reversal: the
“y
-coordinate” is the first function parameter, the “x
-coordinate”
is the second.) By IEEE convention, this function is defined for
x2
= +/-0 and for either or both ofx1
andx2
= +/-inf (see
Notes for specific values).
This function is not defined for complex-valued arguments; for the
so-called argument of complex values, useangle
.
Parameters
x1 : array_like, real-valued
y
-coordinates.
x2 : array_like, real-valued
x
-coordinates. Ifx1.shape != x2.shape
, they must be broadcastable to a common shape (which becomes the shape of the output).
out : ndarray, None, or tuple of ndarray and None, optional
A location into which the result is stored. If provided, it must have
a shape that the inputs broadcast to. If not provided or None,
a freshly-allocated array is returned. A tuple (possible only as a
keyword argument) must have length equal to the number of outputs.
where : array_like, optional
This condition is broadcast over the input. At locations where the
condition is True, theout
array will be set to the ufunc result.
Elsewhere, theout
array will retain its original value.
Note that if an uninitializedout
array is created via the default
out=None
, locations within it where the condition is False will
remain uninitialized.
**kwargs
For other keyword-only arguments, see the
:ref:ufunc docs <ufuncs.kwargs>
.
Returns
angle : ndarray
Array of angles in radians, in the range[-pi, pi]
.
This is a scalar if bothx1
andx2
are scalars.
总结
- arctan2的输入不仅仅是正切值,而是要输入两个数 x 1 x1 x1和 x 2 x2 x2,或者是两者的数组,正切值是两者的比值 x 1 x 2 \frac{x1}{x2} x2x1.
- arctan2的值域是 [ − π , π ] [-\pi, \pi] [−π,π], 因为可以根据 x 1 x1 x1和 x 2 x2 x2来确定点落在哪个象限.
共同点
- 都能够求反正切值
区别
- 两者输入不同, arctan仅仅输入正切值,arctan2要输入对边和直角边的具体数值,用来确定象限
- 两者的值域不同,arctan的值域是 [ − π 2 , π 2 ] [-\frac{\pi}{2}, \frac{\pi}{2}] [−2π,2π], arctan2的值域是 [ − π , π ] [-\pi, \pi] [−π,π]