首页 > 解决方案 > 如何找到两个向量之间的角度,范围从 0 rad 到 2 rad,而不是使用 arccos 函数的内角

问题描述

我现在正在制作一个 python 脚本,它试图找到弧的长度,它给出了以下信息:

圆心:x1, y1

圆弧起点:x2, y2

圆弧终点:x3, y3

方向,顺时针,逆时针

到目前为止,我已经能够成功计算出半径,并尝试使用以下等式计算角度:

角度方程

但是对于任何角度大于 1*pi 或 180 度的弧,它会返回不正确(但正确)的内角。

知道半径和这三个点的正确方程式是什么要么 要么 我需要能够计算这两种情况)

代码:

# code to find theta
aVector = np.array([x1 - x2, y1 - y2])
bVector = np.array([x1 - x3, y1 - y3])
aMag = np.linalg.norm(aVector)
bMag = np.linalg.norm(aVector)
theta = np.arcos(np.dot(aVector, bVector) / (aMag * bMag))

正如你在这里看到的,我使用的是 arccos,令我沮丧的是它只输出 0-180 度

解决方案/工作代码:

# equation for angle using atan2
start = math.atan2(y2 - y1, x2 - x1)
end = math.atan2(y3 - y1, x3 - x1)
if gcodeAnalysis[tempLineNum][4] == "G3": # going CW
    start, end = end, start
tau = 2.0 * math.pi
theta = math.fmod(math.fmod(end - start, tau) + tau, tau)

工作价值观:

X1 = 0.00048399999999998444
Y1 = 0.0002720000000007161
X2 = 0.378484
Y2 = -14.694728
X3 = 3.376
Y3 = -14.307

正确的结果/价值

Theta = 6.077209477545957

假设这个弧是按逆时针方向完成的

标签: pythonnumpymathtrigonometry

解决方案


正如您所注意到的, 的范围math.acos是 [0, pi],因此它对于告诉您向量的相对方向毫无用处。要获得关于一对角度的完整圆形信息,您可以使用math.atan2. 虽然常规math.atan的范围为 [-pi/2, pi/2],atan2但将输入分成两部分并返回范围内的角度 (-pi, pi]。您可以计算相对于任何参考的角度,不一定是相对的对彼此:

start = math.atan2(y2 - y1, x2 - x1)
end = math.atan2(y3 - y1, x3 - x1)

现在你可以使用一些常用的公式来找出你想要的任何方向的角度之间的差异。我已经在我制作的一个名为 haggis 的小型实用程序库中实现了其中的一些。您想要的具体功能是haggis.math.ang_diff_pos.

首先,“手动”计算:

if direction == 'cw':
    start, end = end, start
tau = 2.0 * math.pi
angle = math.fmod(math.fmod(end - start, tau) + tau, tau)

如果你想使用我的功能,你可以做

if direction == 'cw':
    start, end = end, start
angle = ang_diff_pos(start, end)

如果您发现自己同时处理许多点,则所有这些操作都可以使用 numpy 轻松矢量化。


推荐阅读