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

我认为一张图片最能说明我想要的内容:

给定(P1x,P1y)和(P2x,P2y),计算此角度的最佳方法是什么?原点在左上角,仅使用正象限。

最佳答案

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

deltaY = P2_y - P1_y
deltaX = P2_x - P1_x

然后计算角度(从P1的正X轴到P1的正Y轴)。
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI

但是arctan可能并不理想,因为以这种方式划分差异将消除区分角度所在象限所需的区分(请参见下文)。如果您的语言包含atan2函数,请改用以下代码:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI

编辑(2017年2月22日):但是,通常来说,仅为了获得atan2(deltaY,deltaX)cos的正确角度而调用sin可能不太好。在这种情况下,通常可以改为执行以下操作:
  • (deltaX, deltaY)视为向量。
  • 将该向量归一化为单位向量。为此,将deltaXdeltaY除以向量的长度(sqrt(deltaX*deltaX+deltaY*deltaY)),除非长度为0。
  • 之后,deltaX现在将是向量和水平轴之间的角度的余弦值(在P1处,从X轴正方向到Y轴正方向)。
  • deltaY现在将成为该角度的正弦。
  • 如果向量的长度为0,则它​​与水平轴之间将没有角度(因此,它将没有有意义的正弦和余弦)。

  • 编辑(2017年2月28日):即使未规范化(deltaX, deltaY):
  • deltaX的符号将告诉您步骤3中描述的余弦是正还是负。
  • deltaY的符号将告诉您步骤4中描述的正弦是正还是负。
  • deltaXdeltaY的符号会告诉您相对于P1的正X轴,该角度位于哪个象限:
  • +deltaX+deltaY:0到90度。
  • -deltaX+deltaY:90至180度。
  • -deltaX-deltaY:180到270度(-180到-90度)。
  • +deltaX-deltaY:270至360度(-90至0度)。


  • 使用弧度的Python实现(由2015年7月19日由编辑我的答案的Eric Leschinski提供):
    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

    关于c# - 如何计算一条线与水平轴之间的角度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7586063/

    10-12 01:07