如何计算起始向量到终止向量的逆时针弧度角(0-2π)
计算起始向量到终止向量的逆时针弧度角(0至2π)
问题分析
你当前的Elixir代码仅通过点积+反余弦计算夹角,反余弦acos的返回范围是[0, π],无法区分顺时针和逆时针方向。比如示例中{10,0}到{-10,-10},叉积为负(说明终止向量在起始向量顺时针侧),但acos只返回了夹角的绝对值3π/4,而我们需要的逆时针角度是2π - 3π/4 = 5π/4。
调整后的Elixir实现
要得到0到2π的逆时针角度,需要结合叉积判断方向:
- 叉积公式:
cross = x*y1 - y*x1- 若
cross > 0:终止向量在起始向量逆时针侧,角度为acos结果 - 若
cross < 0:终止向量在起始向量顺时针侧,角度为2π - acos结果 - 若
cross = 0:两向量共线,角度为0(同向)或π(反向)
- 若
代码实现:
def get_vector_angle({x, y}, {x1, y1}) do dot = x * x1 + y * y1 mag = :math.sqrt(x*x + y*y) * :math.sqrt(x1*x1 + y1*y1) # 处理零向量情况(可根据需求调整) if mag == 0 do 0.0 else angle = :math.acos(dot / mag) cross = x * y1 - y * x1 if cross >= 0 do angle else 2 * :math.pi() - angle end end end
测试示例:
get_vector_angle({10,0}, {-10,-10}) # 输出:3.9269908169872414(即5π/4)
关于你提供的Erlang代码
这段代码的核心思路是:
- 分别计算两个向量与x轴正方向的夹角(毫度单位)
- 用终止向量的夹角减去起始向量的夹角
- 将结果调整到0-360度范围内,再转成弧度即可得到逆时针角度
但代码逻辑过于繁琐,可参考Elixir的思路简化:通过atan2直接计算向量的极角(范围[-π, π]),再计算差值并调整到[0, 2π]。比如:
vector_angle({Xa, Ya}, {Xb, Yb}) -> AngleA = math:atan2(Ya, Xa), AngleB = math:atan2(Yb, Xb), Diff = AngleB - AngleA, if Diff < 0 -> Diff + 2 * math:pi(); true -> Diff end.
(注:若需处理零向量,可添加对应判断逻辑)
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

