python - 如何找到两个向量之间的角度,范围从 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
假设这个弧是按逆时针方向完成的
解决方案
正如您所注意到的, 的范围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 轻松矢量化。
推荐阅读
- reactjs - 带有表情符号的 ReactJS 文本输入
- batch-file - 批处理 - 删除范围/特定单词
- azure - 多个用户如何认证 R/RW/ADM?在 azure 容器注册表中
- flutter - Flutter setState() 并不总是调用我的构建方法
- html - 本地网站与在线网站不同
- http - 是否可以向任何网站发送获取请求?
- python - 基于轴字符串值的彩色matplotlib条形图
- c++ - 使用模板基类消除工厂类派生类冗余的简洁方法
- scala - 如何在 GraphQL Sangria 中将 Scala Map[String, Seq[String]] 转换为 MapType
- r - 使用 R 在数据集中按月计算的条件一致