小编典典

如何计算直线与水平轴之间的角度?

all

在编程语言(Python、C# 等)中,我需要确定如何计算直线与水平轴之间的角度?

我认为一张图片最能描述我想要的东西:

没有言语可以形容这

给定 (P1 x ,P1 y ) 和 (P2 x ,P2 y ) 计算这个角度的最佳方法是什么?原点位于左上角,仅使用正象限。


阅读 94

收藏
2022-05-17

共1个答案

小编典典

首先找到起点和终点之间的差异(这里,这更像是有向线段,而不是“线”,因为线无限延伸并且不从特定点开始)。

deltaY = P2_y - P1_y
deltaX = P2_x - P1_x

然后计算角度(从 X 轴P1的正向到 Y 轴的正向P1)。

angleInDegrees = arctan(deltaY / deltaX) * 180 / PI

arctan可能并不理想,因为以这种方式划分差异将消除区分角度所在象限所需的差异(见下文)。atan2如果您的语言包含函数,请改用以下内容:

angleInDegrees = atan2(deltaY, deltaX) * 180 / PI

编辑(2017 年 2 月 22
日):但是,总的来说,打电话atan2(deltaY,deltaX)只是为了获得合适的角度,cos并且sin可能不雅。在这些情况下,您通常可以改为执行以下操作:

  1. 视为(deltaX, deltaY)向量。
  2. 将该向量归一化为单位向量。为此,请将deltaXdeltaY除以向量的长度 ( sqrt(deltaX*deltaX+deltaY*deltaY)),除非长度为 0。
  3. 之后,deltaX现在将是向量与水平轴之间的夹角的余弦值(在从正 X 到正 Y 轴的方向P1)。
  4. deltaY现在将是那个角度的正弦。
  5. 如果向量的长度为 0,则它与水平轴之间不会有角度(因此它不会有有意义的正弦和余弦)。

编辑(2017 年 2 月 28 日):即使没有标准化(deltaX, deltaY)

  • 的符号deltaX将告诉您步骤 3 中描述的余弦是正数还是负数。
  • 的符号deltaY将告诉您步骤 4 中描述的正弦是正的还是负的。
  • deltaX和的符号deltaY将告诉您相对于正 X 轴在 处的角度位于哪个象限P1
    • +deltaX, +deltaY: 0 到 90 度。
    • -deltaX, +deltaY: 90 到 180 度。
    • -deltaX, -deltaY: 180 到 270 度(-180 到 -90 度)。
    • +deltaX, -deltaY: 270 到 360 度(-90 到 0 度)。

使用弧度的 Python 实现(由编辑我的答案的 Eric Leschinski 于 2015 年 7 月 19 日提供):

from math import *
def angle_trunc(a):
    while a < 0.0:
        a += pi * 2
    return a

def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
    deltaY = y_landmark - y_orig
    deltaX = x_landmark - x_orig
    return angle_trunc(atan2(deltaY, deltaX))

angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)

所有测试通过。见https://en.wikipedia.org/wiki/Unit_circle

2022-05-17